annotate mercurial/fancyopts.py @ 10281:e7d3b509af8b

Introduce check-code.py check-code is a simple regex-based framework for checking our code and tests for common style and portability errors. Currently, it knows a fair amount about our Python and C style, and a little about common shell script portability problems.
author Matt Mackall <mpm@selenic.com>
date Mon, 25 Jan 2010 00:05:22 -0600
parents 25e572394f5c
children 08a0f04b56bd
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
667
31a9aa890016 A number of minor fixes to problems that pychecker found.
mark.williamson@cl.cam.ac.uk
parents: 608
diff changeset
8 import getopt
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
9
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
10 def gnugetopt(args, options, longoptions):
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
11 """Parse options mostly like getopt.gnu_getopt.
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
12
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
13 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
14 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
15 """
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
16 extraargs = []
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
17 if '--' in args:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
18 stopindex = args.index('--')
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
19 extraargs = args[stopindex+1:]
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
20 args = args[:stopindex]
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
21 opts, parseargs = getopt.getopt(args, options, longoptions)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
22 args = []
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
23 while parseargs:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
24 arg = parseargs.pop(0)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
25 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
26 parseargs.insert(0, arg)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
27 topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
28 opts = opts + topts
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
29 parseargs = newparseargs
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
30 else:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
31 args.append(arg)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
32 args.extend(extraargs)
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
33 return opts, args
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
34
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
35
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
36 def fancyopts(args, options, state, gnu=False):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
37 """
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
38 read args, parse options, and store options in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
39
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
40 each option is a tuple of:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
41
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
42 short option or ''
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
43 long option
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
44 default value
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
45 description
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 option types include:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
48
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
49 boolean or none - option sets variable in state to true
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
50 string - parameter string is stored in state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
51 list - parameter string is added to a list
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
52 integer - parameter strings is stored as int
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
53 function - call function with parameter
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
54
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
55 non-option args are returned
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
56 """
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
57 namelist = []
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
58 shortlist = ''
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
59 argmap = {}
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
60 defmap = {}
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
61
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
62 for short, name, default, comment in options:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
63 # convert opts to getopt format
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
64 oname = name
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
65 name = name.replace('-', '_')
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
66
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
67 argmap['-' + short] = argmap['--' + oname] = name
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
68 defmap[name] = default
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
69
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
70 # copy defaults to state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
71 if isinstance(default, list):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
72 state[name] = default[:]
8366
0bf0045000b5 some modernization cleanups, forward compatibility
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8230
diff changeset
73 elif hasattr(default, '__call__'):
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
74 state[name] = None
5093
88803a69b24a fancyopts: Copy list arguments in command table before modifying.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3749
diff changeset
75 else:
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
76 state[name] = default
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
77
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
78 # does it take a parameter?
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
79 if not (default is None or default is True or default is False):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
80 if short: short += ':'
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
81 if oname: oname += '='
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
82 if short:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
83 shortlist += short
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
84 if name:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
85 namelist.append(oname)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
86
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
87 # parse arguments
7772
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
88 if gnu:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
89 parse = gnugetopt
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
90 else:
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
91 parse = getopt.getopt
88887054d277 fancyopts: Parse options that occur after arguments.
Augie Fackler <durin42@gmail.com>
parents: 5878
diff changeset
92 opts, args = parse(args, shortlist, namelist)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
93
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
94 # transfer result to state
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
95 for opt, val in opts:
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
96 name = argmap[opt]
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
97 t = type(defmap[name])
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
98 if t is type(fancyopts):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
99 state[name] = defmap[name](val)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
100 elif t is type(1):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
101 state[name] = int(val)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
102 elif t is type(''):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
103 state[name] = val
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
104 elif t is type([]):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
105 state[name].append(val)
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
106 elif t is type(None) or t is type(False):
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
107 state[name] = True
209
63af1db35611 Beginning of new command parsing interface
mpm@selenic.com
parents: 164
diff changeset
108
5638
a9b7e425674f fancyopts: lots of cleanups
Matt Mackall <mpm@selenic.com>
parents: 5093
diff changeset
109 # return unparsed args
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
110 return args