annotate mercurial/fancyopts.py @ 27015:341cb90ffd18

util: disable floating point stat times (issue4836) Alternate fix for this issue which avoids putting extra function calls and exception handling in the fast path. For almost all purposes, integer timestamps are preferable to Mercurial. It stores integer timestamps in the dirstate and would thus like to avoid doing any float/int comparisons or conversions. We will continue to have to deal with 1-second granularity on filesystems for quite some time, so this won't significantly hinder our capabilities. This has some impact on our file cache validation code in that it lowers timestamp resolution. But as we still have to deal with low-resolution filesystems, we're not relying on this anyway. An alternate approach is to use stat[ST_MTIME], which is guaranteed to be an integer. But since this support isn't already in our extension, we can't depend on it being available without adding a hard Python->C API dependency that's painful for people like yours truly who have bisect regularly and people without compilers.
author Matt Mackall <mpm@selenic.com>
date Thu, 19 Nov 2015 13:21:24 -0600
parents 56b2bcea2529
children e1f0ec0b7d2d
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
20034
1e5b38a919dd cleanup: move stdlib imports to their own import statement
Augie Fackler <raf@durin42.com>
parents: 17712
diff changeset
10 import getopt
25947
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
11
6002e2d95e54 fancyopts: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25563
diff changeset
12 from .i18n import _
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25947
diff changeset
13 from . import error
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
14
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
15 def gnugetopt(args, options, longoptions):
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
16 """Parse options mostly like getopt.gnu_getopt.
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
17
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
18 This is different from getopt.gnu_getopt in that an argument of - will
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
19 become an argument of - instead of vanishing completely.
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
20 """
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
21 extraargs = []
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
22 if '--' in args:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
23 stopindex = args.index('--')
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
24 extraargs = args[stopindex + 1:]
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
25 args = args[:stopindex]
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
26 opts, parseargs = getopt.getopt(args, options, longoptions)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
27 args = []
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
28 while parseargs:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
29 arg = parseargs.pop(0)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
30 if arg and arg[0] == '-' and len(arg) > 1:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
31 parseargs.insert(0, arg)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
32 topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
33 opts = opts + topts
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
34 parseargs = newparseargs
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
35 else:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
36 args.append(arg)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
37 args.extend(extraargs)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
38 return opts, args
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
39
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
40
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
41 def fancyopts(args, options, state, gnu=False):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
42 """
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
43 read args, parse options, and store options in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
44
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
45 each option is a tuple of:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
46
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
47 short option or ''
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
48 long option
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
49 default value
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
50 description
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
51 option value label(optional)
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
52
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
53 option types include:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
54
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
55 boolean or none - option sets variable in state to true
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
56 string - parameter string is stored in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
57 list - parameter string is added to a list
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
58 integer - parameter strings is stored as int
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
59 function - call function with parameter
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
60
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
61 non-option args are returned
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
62 """
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
63 namelist = []
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
64 shortlist = ''
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
65 argmap = {}
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
66 defmap = {}
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
67
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
68 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
69 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
70 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
71 else:
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10282
diff changeset
72 short, name, default, comment = option
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
73 # convert opts to getopt format
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
74 oname = name
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
75 name = name.replace('-', '_')
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
76
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
77 argmap['-' + short] = argmap['--' + oname] = name
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
78 defmap[name] = default
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
79
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
80 # copy defaults to state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
81 if isinstance(default, list):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
82 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
83 elif callable(default):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
84 state[name] = None
5093
88803a69b24a fancyopts: Copy list arguments in command table before modifying.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3749
diff changeset
85 else:
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
86 state[name] = default
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
87
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
88 # does it take a parameter?
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
89 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
90 if short:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
91 short += ':'
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
92 if oname:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
93 oname += '='
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
94 if short:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
95 shortlist += short
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
96 if name:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
97 namelist.append(oname)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
98
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
99 # parse arguments
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
100 if gnu:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
101 parse = gnugetopt
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
102 else:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
103 parse = getopt.getopt
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
104 opts, args = parse(args, shortlist, namelist)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
105
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
106 # transfer result to state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
107 for opt, val in opts:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
108 name = argmap[opt]
25563
69e8384a436c fancyopts: allow all callable as default parameter value
introom <i@introo.me>
parents: 21794
diff changeset
109 obj = defmap[name]
69e8384a436c fancyopts: allow all callable as default parameter value
introom <i@introo.me>
parents: 21794
diff changeset
110 t = type(obj)
69e8384a436c fancyopts: allow all callable as default parameter value
introom <i@introo.me>
parents: 21794
diff changeset
111 if callable(obj):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
112 state[name] = defmap[name](val)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
113 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
114 try:
c4717f44c1f1 fancyopts: don't show a traceback on invalid integer values
Idan Kamara <idankk86@gmail.com>
parents: 14943
diff changeset
115 state[name] = int(val)
c4717f44c1f1 fancyopts: don't show a traceback on invalid integer values
Idan Kamara <idankk86@gmail.com>
parents: 14943
diff changeset
116 except ValueError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25947
diff changeset
117 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
118 'expected int') % (val, opt))
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
119 elif t is type(''):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
120 state[name] = val
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
121 elif t is type([]):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
122 state[name].append(val)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
123 elif t is type(None) or t is type(False):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
124 state[name] = True
209
63af1db35611 Beginning of new command parsing interface
mpm@selenic.com
parents: 164
diff changeset
125
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
126 # return unparsed args
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
127 return args