##// END OF EJS Templates
fancyopts: allow all callable as default parameter value...
introom -
r25563:69e8384a default
parent child Browse files
Show More
@@ -1,123 +1,124 b''
1 # fancyopts.py - better command line parsing
1 # fancyopts.py - better command line parsing
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import getopt
8 import getopt
9 import util
9 import util
10 from i18n import _
10 from i18n import _
11
11
12 def gnugetopt(args, options, longoptions):
12 def gnugetopt(args, options, longoptions):
13 """Parse options mostly like getopt.gnu_getopt.
13 """Parse options mostly like getopt.gnu_getopt.
14
14
15 This is different from getopt.gnu_getopt in that an argument of - will
15 This is different from getopt.gnu_getopt in that an argument of - will
16 become an argument of - instead of vanishing completely.
16 become an argument of - instead of vanishing completely.
17 """
17 """
18 extraargs = []
18 extraargs = []
19 if '--' in args:
19 if '--' in args:
20 stopindex = args.index('--')
20 stopindex = args.index('--')
21 extraargs = args[stopindex + 1:]
21 extraargs = args[stopindex + 1:]
22 args = args[:stopindex]
22 args = args[:stopindex]
23 opts, parseargs = getopt.getopt(args, options, longoptions)
23 opts, parseargs = getopt.getopt(args, options, longoptions)
24 args = []
24 args = []
25 while parseargs:
25 while parseargs:
26 arg = parseargs.pop(0)
26 arg = parseargs.pop(0)
27 if arg and arg[0] == '-' and len(arg) > 1:
27 if arg and arg[0] == '-' and len(arg) > 1:
28 parseargs.insert(0, arg)
28 parseargs.insert(0, arg)
29 topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
29 topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
30 opts = opts + topts
30 opts = opts + topts
31 parseargs = newparseargs
31 parseargs = newparseargs
32 else:
32 else:
33 args.append(arg)
33 args.append(arg)
34 args.extend(extraargs)
34 args.extend(extraargs)
35 return opts, args
35 return opts, args
36
36
37
37
38 def fancyopts(args, options, state, gnu=False):
38 def fancyopts(args, options, state, gnu=False):
39 """
39 """
40 read args, parse options, and store options in state
40 read args, parse options, and store options in state
41
41
42 each option is a tuple of:
42 each option is a tuple of:
43
43
44 short option or ''
44 short option or ''
45 long option
45 long option
46 default value
46 default value
47 description
47 description
48 option value label(optional)
48 option value label(optional)
49
49
50 option types include:
50 option types include:
51
51
52 boolean or none - option sets variable in state to true
52 boolean or none - option sets variable in state to true
53 string - parameter string is stored in state
53 string - parameter string is stored in state
54 list - parameter string is added to a list
54 list - parameter string is added to a list
55 integer - parameter strings is stored as int
55 integer - parameter strings is stored as int
56 function - call function with parameter
56 function - call function with parameter
57
57
58 non-option args are returned
58 non-option args are returned
59 """
59 """
60 namelist = []
60 namelist = []
61 shortlist = ''
61 shortlist = ''
62 argmap = {}
62 argmap = {}
63 defmap = {}
63 defmap = {}
64
64
65 for option in options:
65 for option in options:
66 if len(option) == 5:
66 if len(option) == 5:
67 short, name, default, comment, dummy = option
67 short, name, default, comment, dummy = option
68 else:
68 else:
69 short, name, default, comment = option
69 short, name, default, comment = option
70 # convert opts to getopt format
70 # convert opts to getopt format
71 oname = name
71 oname = name
72 name = name.replace('-', '_')
72 name = name.replace('-', '_')
73
73
74 argmap['-' + short] = argmap['--' + oname] = name
74 argmap['-' + short] = argmap['--' + oname] = name
75 defmap[name] = default
75 defmap[name] = default
76
76
77 # copy defaults to state
77 # copy defaults to state
78 if isinstance(default, list):
78 if isinstance(default, list):
79 state[name] = default[:]
79 state[name] = default[:]
80 elif callable(default):
80 elif callable(default):
81 state[name] = None
81 state[name] = None
82 else:
82 else:
83 state[name] = default
83 state[name] = default
84
84
85 # does it take a parameter?
85 # does it take a parameter?
86 if not (default is None or default is True or default is False):
86 if not (default is None or default is True or default is False):
87 if short:
87 if short:
88 short += ':'
88 short += ':'
89 if oname:
89 if oname:
90 oname += '='
90 oname += '='
91 if short:
91 if short:
92 shortlist += short
92 shortlist += short
93 if name:
93 if name:
94 namelist.append(oname)
94 namelist.append(oname)
95
95
96 # parse arguments
96 # parse arguments
97 if gnu:
97 if gnu:
98 parse = gnugetopt
98 parse = gnugetopt
99 else:
99 else:
100 parse = getopt.getopt
100 parse = getopt.getopt
101 opts, args = parse(args, shortlist, namelist)
101 opts, args = parse(args, shortlist, namelist)
102
102
103 # transfer result to state
103 # transfer result to state
104 for opt, val in opts:
104 for opt, val in opts:
105 name = argmap[opt]
105 name = argmap[opt]
106 t = type(defmap[name])
106 obj = defmap[name]
107 if t is type(fancyopts):
107 t = type(obj)
108 if callable(obj):
108 state[name] = defmap[name](val)
109 state[name] = defmap[name](val)
109 elif t is type(1):
110 elif t is type(1):
110 try:
111 try:
111 state[name] = int(val)
112 state[name] = int(val)
112 except ValueError:
113 except ValueError:
113 raise util.Abort(_('invalid value %r for option %s, '
114 raise util.Abort(_('invalid value %r for option %s, '
114 'expected int') % (val, opt))
115 'expected int') % (val, opt))
115 elif t is type(''):
116 elif t is type(''):
116 state[name] = val
117 state[name] = val
117 elif t is type([]):
118 elif t is type([]):
118 state[name].append(val)
119 state[name].append(val)
119 elif t is type(None) or t is type(False):
120 elif t is type(None) or t is type(False):
120 state[name] = True
121 state[name] = True
121
122
122 # return unparsed args
123 # return unparsed args
123 return args
124 return args
General Comments 0
You need to be logged in to leave comments. Login now