mercurial/fancyopts.py
author Gregory Szorc <gregory.szorc@gmail.com>
Wed, 31 Jan 2018 14:05:11 -0800
changeset 35981 ef683a0fd21f
parent 35227 98a5aa5575e7
child 36353 cc9d0763c8e9
permissions -rw-r--r--
wireproto: define and use types for wire protocol commands Wire protocol commands have historically been declared as 2-tuples in wireproto.commands. There are some additional features I'd like to implement that require going beyond 2-tuples. But because the 2-tuple API (both destructuring assignment and direct assignment into the dict) is used throughout the code base and in 3rd party extensions, we can't do a trivial type change. This commit creates a new "commandentry" type to represent declared wire protocol commands. It implements __getitem__ and __iter__ so it can quack like a 2-tuple. The @wireprotocommand decorator now creates "commandentry" instances. We also create a "commanddict" type to represent the dictionary of declared wire protocol commands. It inherits from "dict" but provides a custom __setitem__ to coerce passed 2-tuples to "commandentry" instances. wireproto.commands is now an instance of this type. Various callers in core rely on the new functionality. And tests pass. So I'm reasonably confident things will "just work" in 3rd party extensions as well. Differential Revision: https://phab.mercurial-scm.org/D1998
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8230
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     1
# fancyopts.py - better command line parsing
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     2
#
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     3
#  Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     4
#
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
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: 8366
diff changeset
     6
# GNU General Public License version 2 or any later version.
8230
ec98f35e3e16 fancyopts: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7772
diff changeset
     7
25947
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
     8
from __future__ import absolute_import
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
     9
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    10
import functools
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    11
25947
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
    12
from .i18n import _
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
    13
from . import (
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
    14
    error,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
    15
    pycompat,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
    16
)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    17
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    18
# Set of flags to not apply boolean negation logic on
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 30578
diff changeset
    19
nevernegate = {
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    20
    # avoid --no-noninteractive
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    21
    'noninteractive',
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    22
    # These two flags are special because they cause hg to do one
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    23
    # thing and then exit, and so aren't suitable for use in things
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    24
    # like aliases anyway.
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    25
    'help',
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    26
    'version',
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 30578
diff changeset
    27
}
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
    28
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    29
def _earlyoptarg(arg, shortlist, namelist):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    30
    """Check if the given arg is a valid unabbreviated option
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    31
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    32
    Returns (flag_str, has_embedded_value?, embedded_value, takes_value?)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    33
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    34
    >>> def opt(arg):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    35
    ...     return _earlyoptarg(arg, b'R:q', [b'cwd=', b'debugger'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    36
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    37
    long form:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    38
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    39
    >>> opt(b'--cwd')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    40
    ('--cwd', False, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    41
    >>> opt(b'--cwd=')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    42
    ('--cwd', True, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    43
    >>> opt(b'--cwd=foo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    44
    ('--cwd', True, 'foo', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    45
    >>> opt(b'--debugger')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    46
    ('--debugger', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    47
    >>> opt(b'--debugger=')  # invalid but parsable
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    48
    ('--debugger', True, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    49
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    50
    short form:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    51
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    52
    >>> opt(b'-R')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    53
    ('-R', False, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    54
    >>> opt(b'-Rfoo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    55
    ('-R', True, 'foo', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    56
    >>> opt(b'-q')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    57
    ('-q', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    58
    >>> opt(b'-qfoo')  # invalid but parsable
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    59
    ('-q', True, 'foo', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    60
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    61
    unknown or invalid:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    62
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    63
    >>> opt(b'--unknown')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    64
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    65
    >>> opt(b'-u')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    66
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    67
    >>> opt(b'-ufoo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    68
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    69
    >>> opt(b'--')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    70
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    71
    >>> opt(b'-')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    72
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    73
    >>> opt(b'-:')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    74
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    75
    >>> opt(b'-:foo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    76
    ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    77
    """
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    78
    if arg.startswith('--'):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    79
        flag, eq, val = arg.partition('=')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    80
        if flag[2:] in namelist:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    81
            return flag, bool(eq), val, False
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    82
        if flag[2:] + '=' in namelist:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    83
            return flag, bool(eq), val, True
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    84
    elif arg.startswith('-') and arg != '-' and not arg.startswith('-:'):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    85
        flag, val = arg[:2], arg[2:]
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    86
        i = shortlist.find(flag[1:])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    87
        if i >= 0:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    88
            return flag, bool(val), val, shortlist.startswith(':', i + 1)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    89
    return '', False, '', False
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    90
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    91
def earlygetopt(args, shortlist, namelist, gnu=False, keepsep=False):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    92
    """Parse options like getopt, but ignores unknown options and abbreviated
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    93
    forms
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    94
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    95
    If gnu=False, this stops processing options as soon as a non/unknown-option
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    96
    argument is encountered. Otherwise, option and non-option arguments may be
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    97
    intermixed, and unknown-option arguments are taken as non-option.
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    98
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
    99
    If keepsep=True, '--' won't be removed from the list of arguments left.
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   100
    This is useful for stripping early options from a full command arguments.
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   101
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   102
    >>> def get(args, gnu=False, keepsep=False):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   103
    ...     return earlygetopt(args, b'R:q', [b'cwd=', b'debugger'],
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   104
    ...                        gnu=gnu, keepsep=keepsep)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   105
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   106
    default parsing rules for early options:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   107
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   108
    >>> get([b'x', b'--cwd', b'foo', b'-Rbar', b'-q', b'y'], gnu=True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   109
    ([('--cwd', 'foo'), ('-R', 'bar'), ('-q', '')], ['x', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   110
    >>> get([b'x', b'--cwd=foo', b'y', b'-R', b'bar', b'--debugger'], gnu=True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   111
    ([('--cwd', 'foo'), ('-R', 'bar'), ('--debugger', '')], ['x', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   112
    >>> get([b'--unknown', b'--cwd=foo', b'--', '--debugger'], gnu=True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   113
    ([('--cwd', 'foo')], ['--unknown', '--debugger'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   114
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   115
    restricted parsing rules (early options must come first):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   116
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   117
    >>> get([b'--cwd', b'foo', b'-Rbar', b'x', b'-q', b'y'], gnu=False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   118
    ([('--cwd', 'foo'), ('-R', 'bar')], ['x', '-q', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   119
    >>> get([b'--cwd=foo', b'x', b'y', b'-R', b'bar', b'--debugger'], gnu=False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   120
    ([('--cwd', 'foo')], ['x', 'y', '-R', 'bar', '--debugger'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   121
    >>> get([b'--unknown', b'--cwd=foo', b'--', '--debugger'], gnu=False)
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   122
    ([], ['--unknown', '--cwd=foo', '--', '--debugger'])
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   123
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   124
    stripping early options (without loosing '--'):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   125
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   126
    >>> get([b'x', b'-Rbar', b'--', '--debugger'], gnu=True, keepsep=True)[1]
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   127
    ['x', '--', '--debugger']
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   128
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   129
    last argument:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   130
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   131
    >>> get([b'--cwd'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   132
    ([], ['--cwd'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   133
    >>> get([b'--cwd=foo'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   134
    ([('--cwd', 'foo')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   135
    >>> get([b'-R'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   136
    ([], ['-R'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   137
    >>> get([b'-Rbar'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   138
    ([('-R', 'bar')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   139
    >>> get([b'-q'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   140
    ([('-q', '')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   141
    >>> get([b'-q', b'--'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   142
    ([('-q', '')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   143
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   144
    '--' may be a value:
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   145
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   146
    >>> get([b'-R', b'--', b'x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   147
    ([('-R', '--')], ['x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   148
    >>> get([b'--cwd', b'--', b'x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   149
    ([('--cwd', '--')], ['x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   150
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   151
    value passed to bool options:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   152
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   153
    >>> get([b'--debugger=foo', b'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   154
    ([], ['--debugger=foo', 'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   155
    >>> get([b'-qfoo', b'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   156
    ([], ['-qfoo', 'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   157
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   158
    short option isn't separated with '=':
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   159
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   160
    >>> get([b'-R=bar'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   161
    ([('-R', '=bar')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   162
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   163
    ':' may be in shortlist, but shouldn't be taken as an option letter:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   164
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   165
    >>> get([b'-:', b'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   166
    ([], ['-:', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   167
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   168
    '-' is a valid non-option argument:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   170
    >>> get([b'-', b'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   171
    ([], ['-', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   172
    """
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   173
    parsedopts = []
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   174
    parsedargs = []
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   175
    pos = 0
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   176
    while pos < len(args):
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   177
        arg = args[pos]
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   178
        if arg == '--':
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   179
            pos += not keepsep
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   180
            break
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   181
        flag, hasval, val, takeval = _earlyoptarg(arg, shortlist, namelist)
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   182
        if not hasval and takeval and pos + 1 >= len(args):
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   183
            # missing last argument
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   184
            break
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   185
        if not flag or hasval and not takeval:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   186
            # non-option argument or -b/--bool=INVALID_VALUE
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   187
            if gnu:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   188
                parsedargs.append(arg)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   189
                pos += 1
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   190
            else:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   191
                break
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   192
        elif hasval == takeval:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   193
            # -b/--bool or -s/--str=VALUE
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   194
            parsedopts.append((flag, val))
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   195
            pos += 1
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   196
        else:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   197
            # -s/--str VALUE
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   198
            parsedopts.append((flag, args[pos + 1]))
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   199
            pos += 2
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   200
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
   201
    parsedargs.extend(args[pos:])
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   202
    return parsedopts, parsedargs
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   203
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   204
def fancyopts(args, options, state, gnu=False, early=False, optaliases=None):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   205
    """
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   206
    read args, parse options, and store options in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   207
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   208
    each option is a tuple of:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   209
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   210
      short option or ''
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   211
      long option
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   212
      default value
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   213
      description
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   214
      option value label(optional)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   215
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   216
    option types include:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   217
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   218
      boolean or none - option sets variable in state to true
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   219
      string - parameter string is stored in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   220
      list - parameter string is added to a list
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   221
      integer - parameter strings is stored as int
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   222
      function - call function with parameter
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   223
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   224
    optaliases is a mapping from a canonical option name to a list of
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   225
    additional long options. This exists for preserving backward compatibility
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   226
    of early options. If we want to use it extensively, please consider moving
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   227
    the functionality to the options table (e.g separate long options by '|'.)
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   228
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   229
    non-option args are returned
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   230
    """
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   231
    if optaliases is None:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   232
        optaliases = {}
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   233
    namelist = []
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   234
    shortlist = ''
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   235
    argmap = {}
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   236
    defmap = {}
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   237
    negations = {}
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   238
    alllong = set(o[1] for o in options)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   239
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   240
    for option in options:
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   241
        if len(option) == 5:
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   242
            short, name, default, comment, dummy = option
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   243
        else:
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
   244
            short, name, default, comment = option
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   245
        # convert opts to getopt format
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   246
        onames = [name]
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   247
        onames.extend(optaliases.get(name, []))
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   248
        name = name.replace('-', '_')
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   249
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   250
        argmap['-' + short] = name
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   251
        for n in onames:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   252
            argmap['--' + n] = name
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   253
        defmap[name] = default
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   254
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   255
        # copy defaults to state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   256
        if isinstance(default, list):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   257
            state[name] = default[:]
21794
753af9ee7c81 fancyopts: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 20034
diff changeset
   258
        elif callable(default):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   259
            state[name] = None
5093
88803a69b24a fancyopts: Copy list arguments in command table before modifying.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3749
diff changeset
   260
        else:
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   261
            state[name] = default
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   262
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   263
        # does it take a parameter?
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   264
        if not (default is None or default is True or default is False):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   265
            if short:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   266
                short += ':'
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   267
            onames = [n + '=' for n in onames]
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   268
        elif name not in nevernegate:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   269
            for n in onames:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   270
                if n.startswith('no-'):
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   271
                    insert = n[3:]
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   272
                else:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   273
                    insert = 'no-' + n
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   274
                # backout (as a practical example) has both --commit and
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   275
                # --no-commit options, so we don't want to allow the
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   276
                # negations of those flags.
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   277
                if insert not in alllong:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   278
                    assert ('--' + n) not in negations
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   279
                    negations['--' + insert] = '--' + n
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   280
                    namelist.append(insert)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   281
        if short:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   282
            shortlist += short
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   283
        if name:
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
   284
            namelist.extend(onames)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   285
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   286
    # parse arguments
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   287
    if early:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   288
        parse = functools.partial(earlygetopt, gnu=gnu)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
   289
    elif gnu:
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
   290
        parse = pycompat.gnugetoptb
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
   291
    else:
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
   292
        parse = pycompat.getoptb
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
   293
    opts, args = parse(args, shortlist, namelist)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   294
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   295
    # transfer result to state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   296
    for opt, val in opts:
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   297
        boolval = True
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   298
        negation = negations.get(opt, False)
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   299
        if negation:
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   300
            opt = negation
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   301
            boolval = False
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   302
        name = argmap[opt]
25563
69e8384a436c fancyopts: allow all callable as default parameter value
introom <i@introo.me>
parents: 21794
diff changeset
   303
        obj = defmap[name]
69e8384a436c fancyopts: allow all callable as default parameter value
introom <i@introo.me>
parents: 21794
diff changeset
   304
        t = type(obj)
69e8384a436c fancyopts: allow all callable as default parameter value
introom <i@introo.me>
parents: 21794
diff changeset
   305
        if callable(obj):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   306
            state[name] = defmap[name](val)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   307
        elif t is type(1):
17712
c4717f44c1f1 fancyopts: don't show a traceback on invalid integer values
Idan Kamara <idankk86@gmail.com>
parents: 14943
diff changeset
   308
            try:
c4717f44c1f1 fancyopts: don't show a traceback on invalid integer values
Idan Kamara <idankk86@gmail.com>
parents: 14943
diff changeset
   309
                state[name] = int(val)
c4717f44c1f1 fancyopts: don't show a traceback on invalid integer values
Idan Kamara <idankk86@gmail.com>
parents: 14943
diff changeset
   310
            except ValueError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25947
diff changeset
   311
                raise error.Abort(_('invalid value %r for option %s, '
17712
c4717f44c1f1 fancyopts: don't show a traceback on invalid integer values
Idan Kamara <idankk86@gmail.com>
parents: 14943
diff changeset
   312
                                   'expected int') % (val, opt))
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   313
        elif t is type(''):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   314
            state[name] = val
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   315
        elif t is type([]):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   316
            state[name].append(val)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   317
        elif t is type(None) or t is type(False):
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
   318
            state[name] = boolval
209
63af1db35611 Beginning of new command parsing interface
mpm@selenic.com
parents: 164
diff changeset
   319
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
   320
    # return unparsed args
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   321
    return args