annotate mercurial/fancyopts.py @ 46490:86b019899737 stable

hooks: forbid ':' in hook name The `:` character is a special separator in the config and it seems same do to the same for hooks. This is necessary to improve the experience around the HGPLAIN behavior change in 5.7. See next changesets for details. Differential Revision: https://phab.mercurial-scm.org/D9978
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 10 Feb 2021 21:05:05 +0100
parents 2eb8ad899fa6
children d4ba4d51f85f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
10 import abc
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
11 import functools
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
12
25947
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
13 from .i18n import _
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
14 from . import (
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
15 error,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
16 pycompat,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
17 )
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
18
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
19 # 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
20 nevernegate = {
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
21 # avoid --no-noninteractive
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
22 b'noninteractive',
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
23 # 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
24 # 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
25 # like aliases anyway.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
26 b'help',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
27 b'version',
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 30578
diff changeset
28 }
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
29
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
30
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
31 def _earlyoptarg(arg, shortlist, namelist):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
32 """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
33
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
34 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
35
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
36 >>> def opt(arg):
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
37 ... 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
38
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
39 long form:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
40
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', False, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
43 >>> opt(b'--cwd=')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
44 ('--cwd', True, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
45 >>> opt(b'--cwd=foo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
46 ('--cwd', True, 'foo', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
47 >>> opt(b'--debugger')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
48 ('--debugger', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
49 >>> opt(b'--debugger=') # invalid but parsable
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
50 ('--debugger', True, '', False)
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 short form:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
53
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
54 >>> opt(b'-R')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
55 ('-R', False, '', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
56 >>> opt(b'-Rfoo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
57 ('-R', True, 'foo', True)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
58 >>> opt(b'-q')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
59 ('-q', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
60 >>> opt(b'-qfoo') # invalid but parsable
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
61 ('-q', True, 'foo', False)
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 unknown or invalid:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
64
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
65 >>> opt(b'--unknown')
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'-u')
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'-ufoo')
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'-:')
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 >>> opt(b'-:foo')
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
78 ('', False, '', False)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
79 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
80 if arg.startswith(b'--'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
81 flag, eq, val = arg.partition(b'=')
35169
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, False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
84 if flag[2:] + b'=' in namelist:
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
85 return flag, bool(eq), val, True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
86 elif arg.startswith(b'-') and arg != b'-' and not arg.startswith(b'-:'):
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
87 flag, val = arg[:2], arg[2:]
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
88 i = shortlist.find(flag[1:])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
89 if i >= 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
90 return flag, bool(val), val, shortlist.startswith(b':', i + 1)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
91 return b'', False, b'', False
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
92
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
93
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
94 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
95 """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
96 forms
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
97
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
98 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
99 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
100 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
101
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
102 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
103 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
104
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
105 >>> 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
106 ... 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
107 ... gnu=gnu, keepsep=keepsep)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
108
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
109 default parsing rules for early options:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
110
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
111 >>> 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
112 ([('--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
113 >>> 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
114 ([('--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
115 >>> 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
116 ([('--cwd', 'foo')], ['--unknown', '--debugger'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
117
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
118 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
119
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
120 >>> 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
121 ([('--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
122 >>> 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
123 ([('--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
124 >>> 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
125 ([], ['--unknown', '--cwd=foo', '--', '--debugger'])
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
126
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
127 stripping early options (without loosing '--'):
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 >>> 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
130 ['x', '--', '--debugger']
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
131
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
132 last argument:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
133
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
134 >>> get([b'--cwd'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
135 ([], ['--cwd'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
136 >>> get([b'--cwd=foo'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
137 ([('--cwd', 'foo')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
138 >>> get([b'-R'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
139 ([], ['-R'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
140 >>> get([b'-Rbar'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
141 ([('-R', 'bar')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
142 >>> get([b'-q'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
143 ([('-q', '')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
144 >>> get([b'-q', b'--'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
145 ([('-q', '')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
146
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
147 '--' may be a value:
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
148
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
149 >>> get([b'-R', b'--', b'x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
150 ([('-R', '--')], ['x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
151 >>> get([b'--cwd', b'--', b'x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
152 ([('--cwd', '--')], ['x'])
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
153
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
154 value passed to bool options:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
155
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
156 >>> get([b'--debugger=foo', b'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
157 ([], ['--debugger=foo', 'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
158 >>> get([b'-qfoo', b'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
159 ([], ['-qfoo', 'x'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
160
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
161 short option isn't separated with '=':
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 >>> get([b'-R=bar'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
164 ([('-R', '=bar')], [])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
165
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
166 ':' 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
167
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
168 >>> get([b'-:', b'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
169 ([], ['-:', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
170
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
171 '-' is a valid non-option argument:
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 >>> get([b'-', b'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
174 ([], ['-', 'y'])
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
175 """
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
176 parsedopts = []
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
177 parsedargs = []
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
178 pos = 0
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
179 while pos < len(args):
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
180 arg = args[pos]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
181 if arg == b'--':
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
182 pos += not keepsep
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
183 break
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
184 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
185 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
186 # missing last argument
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
187 break
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
188 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
189 # 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
190 if gnu:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
191 parsedargs.append(arg)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
192 pos += 1
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
193 else:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
194 break
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
195 elif hasval == takeval:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
196 # -b/--bool or -s/--str=VALUE
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
197 parsedopts.append((flag, val))
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
198 pos += 1
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
199 else:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
200 # -s/--str VALUE
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
201 parsedopts.append((flag, args[pos + 1]))
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
202 pos += 2
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
203
35227
98a5aa5575e7 fancyopts: fix handling of "--" value in earlygetopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35226
diff changeset
204 parsedargs.extend(args[pos:])
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
205 return parsedopts, parsedargs
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
206
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
207
43474
70d42e2ad9b4 pytype: don't warn us about ignored-on-py3 metaclasses
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
208 class customopt(object): # pytype: disable=ignored-metaclass
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
209 """Manage defaults and mutations for any type of opt."""
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
210
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
211 __metaclass__ = abc.ABCMeta
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
212
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
213 def __init__(self, defaultvalue):
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
214 self._defaultvalue = defaultvalue
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
215
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
216 def _isboolopt(self):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
217 return False
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
218
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
219 def getdefaultvalue(self):
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
220 """Returns the default value for this opt.
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
221
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
222 Subclasses should override this to return a new value if the value type
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
223 is mutable."""
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
224 return self._defaultvalue
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
225
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
226 @abc.abstractmethod
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
227 def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
228 """Adds newparam to oldstate and returns the new state.
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
229
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
230 On failure, abort can be called with a string error message."""
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
231
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
232
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
233 class _simpleopt(customopt):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
234 def _isboolopt(self):
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
235 return isinstance(self._defaultvalue, (bool, type(None)))
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
236
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
237 def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
238 return newparam
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
239
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
240
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
241 class _callableopt(customopt):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
242 def __init__(self, callablefn):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
243 self.callablefn = callablefn
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
244 super(_callableopt, self).__init__(None)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
245
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
246 def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
247 return self.callablefn(newparam)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
248
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
249
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
250 class _listopt(customopt):
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
251 def getdefaultvalue(self):
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
252 return self._defaultvalue[:]
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
253
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
254 def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
255 oldstate.append(newparam)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
256 return oldstate
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
257
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
258
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
259 class _intopt(customopt):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
260 def newstate(self, oldstate, newparam, abort):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
261 try:
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
262 return int(newparam)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
263 except ValueError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
264 abort(_(b'expected int'))
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
265
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
266
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
267 def _defaultopt(default):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
268 """Returns a default opt implementation, given a default value."""
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
269
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
270 if isinstance(default, customopt):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
271 return default
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
272 elif callable(default):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
273 return _callableopt(default)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
274 elif isinstance(default, list):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
275 return _listopt(default[:])
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
276 elif type(default) is type(1):
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
277 return _intopt(default)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
278 else:
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
279 return _simpleopt(default)
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
280
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
281
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
282 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
283 """
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
284 read args, parse options, and store options in state
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 each option is a tuple of:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
287
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
288 short option or ''
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
289 long option
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
290 default value
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
291 description
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
292 option value label(optional)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
293
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
294 option types include:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
295
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
296 boolean or none - option sets variable in state to true
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
297 string - parameter string is stored in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
298 list - parameter string is added to a list
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
299 integer - parameter strings is stored as int
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
300 function - call function with parameter
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
301 customopt - subclass of 'customopt'
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
302
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
303 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
304 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
305 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
306 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
307
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
308 non-option args are returned
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
309 """
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
310 if optaliases is None:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
311 optaliases = {}
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
312 namelist = []
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
313 shortlist = b''
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
314 argmap = {}
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
315 defmap = {}
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
316 negations = {}
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43474
diff changeset
317 alllong = {o[1] for o in options}
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
318
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
319 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
320 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
321 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
322 else:
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
323 short, name, default, comment = option
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
324 # 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
325 onames = [name]
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
326 onames.extend(optaliases.get(name, []))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
327 name = name.replace(b'-', b'_')
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
328
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
329 argmap[b'-' + short] = name
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
330 for n in onames:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
331 argmap[b'--' + n] = name
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
332 defmap[name] = _defaultopt(default)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
333
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
334 # copy defaults to state
37092
ef6215df2402 fancyopts: prevent mutation of the default value in customopts
Daniel Ploch <dploch@google.com>
parents: 36383
diff changeset
335 state[name] = defmap[name].getdefaultvalue()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
336
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
337 # does it take a parameter?
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
338 if not defmap[name]._isboolopt():
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
339 if short:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
340 short += b':'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
341 onames = [n + b'=' for n in onames]
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
342 elif name not in nevernegate:
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
343 for n in onames:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
344 if n.startswith(b'no-'):
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
345 insert = n[3:]
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
346 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
347 insert = b'no-' + n
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
348 # 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
349 # --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
350 # negations of those flags.
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
351 if insert not in alllong:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
352 assert (b'--' + n) not in negations
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
353 negations[b'--' + insert] = b'--' + n
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
354 namelist.append(insert)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
355 if short:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
356 shortlist += short
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
357 if name:
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35169
diff changeset
358 namelist.extend(onames)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
359
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
360 # parse arguments
35169
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
361 if early:
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
362 parse = functools.partial(earlygetopt, gnu=gnu)
898c6f812a51 fancyopts: add early-options parser compatible with getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 33103
diff changeset
363 elif gnu:
35226
5b569d512fbd fancyopts: use getopt.gnu_getopt()
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
364 parse = pycompat.gnugetoptb
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
365 else:
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29947
diff changeset
366 parse = pycompat.getoptb
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
367 opts, args = parse(args, shortlist, namelist)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
368
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
369 # transfer result to state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
370 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
371 boolval = True
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
372 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
373 if negation:
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
374 opt = negation
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
375 boolval = False
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
376 name = argmap[opt]
25563
69e8384a436c fancyopts: allow all callable as default parameter value
introom <i@introo.me>
parents: 21794
diff changeset
377 obj = defmap[name]
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
378 if obj._isboolopt():
29947
e1f0ec0b7d2d flags: allow specifying --no-boolean-flag on the command line (BC)
Augie Fackler <augie@google.com>
parents: 26587
diff changeset
379 state[name] = boolval
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
380 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
381
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
382 def abort(s):
45837
2eb8ad899fa6 errors: raise InputError in fancyopts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44452
diff changeset
383 raise error.InputError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
384 _(b'invalid value %r for option %s, %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
385 % (pycompat.maybebytestr(val), opt, s)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
386 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 37465
diff changeset
387
36353
cc9d0763c8e9 fancyopts: add support for custom multi-arg opts in fancyopts.py
Daniel Ploch <dploch@google.com>
parents: 35227
diff changeset
388 state[name] = defmap[name].newstate(state[name], val, abort)
209
63af1db35611 Beginning of new command parsing interface
mpm@selenic.com
parents: 164
diff changeset
389
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
390 # return unparsed args
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
391 return args