chiark / gitweb /
499927269d0a3affbd3e3cf742a7b5b29d4bff45
[stgit] / stgit / argparse.py
1 """Utility functions for command-line option parsing."""
2
3 import optparse, sys
4 from stgit import utils
5 from stgit.config import config
6
7 def sign_options():
8     def callback(option, opt_str, value, parser, sign_str):
9         if parser.values.sign_str not in [None, sign_str]:
10             raise optparse.OptionValueError(
11                 '--ack and --sign were both specified')
12         parser.values.sign_str = sign_str
13     return [optparse.make_option('--sign', action = 'callback',
14                                  callback = callback, dest = 'sign_str',
15                                  callback_args = ('Signed-off-by',),
16                                  help = 'add Signed-off-by line'),
17             optparse.make_option('--ack', action = 'callback',
18                                  callback = callback, dest = 'sign_str',
19                                  callback_args = ('Acked-by',),
20                                  help = 'add Acked-by line')]
21
22 def message_options():
23     def no_dup(parser):
24         if parser.values.message != None:
25             raise optparse.OptionValueError(
26                 'Cannot give more than one --message or --file')
27     def no_combine(parser):
28         if (parser.values.message != None
29             and parser.values.save_template != None):
30             raise optparse.OptionValueError(
31                 'Cannot give both --message/--file and --save-template')
32     def msg_callback(option, opt_str, value, parser):
33         no_dup(parser)
34         parser.values.message = value
35         no_combine(parser)
36     def file_callback(option, opt_str, value, parser):
37         no_dup(parser)
38         if value == '-':
39             parser.values.message = sys.stdin.read()
40         else:
41             f = file(value)
42             parser.values.message = f.read()
43             f.close()
44         no_combine(parser)
45     def templ_callback(option, opt_str, value, parser):
46         if value == '-':
47             def w(s):
48                 sys.stdout.write(s)
49         else:
50             def w(s):
51                 f = file(value, 'w+')
52                 f.write(s)
53                 f.close()
54         parser.values.save_template = w
55         no_combine(parser)
56     m = optparse.make_option
57     return [m('-m', '--message', action = 'callback', callback = msg_callback,
58               dest = 'message', type = 'string',
59               help = 'use MESSAGE instead of invoking the editor'),
60             m('-f', '--file', action = 'callback', callback = file_callback,
61               dest = 'message', type = 'string', metavar = 'FILE',
62               help = 'use FILE instead of invoking the editor'),
63             m('--save-template', action = 'callback', callback = templ_callback,
64               metavar = 'FILE', dest = 'save_template', type = 'string',
65               help = 'save the message template to FILE and exit')]
66
67 def diff_opts_option():
68     def diff_opts_callback(option, opt_str, value, parser):
69         if value:
70             parser.values.diff_flags.extend(value.split())
71         else:
72             parser.values.diff_flags = []
73     return [optparse.make_option(
74         '-O', '--diff-opts', dest = 'diff_flags',
75         default = (config.get('stgit.diff-opts') or '').split(),
76         action = 'callback', callback = diff_opts_callback,
77         type = 'string', metavar = 'OPTIONS',
78         help = 'extra options to pass to "git diff"')]
79
80 def person_opts(person, short):
81     """Sets options.<person> to a function that modifies a Person
82     according to the commandline options."""
83     def short_callback(option, opt_str, value, parser, field):
84         f = getattr(parser.values, person)
85         setattr(parser.values, person,
86                 lambda p: getattr(f(p), 'set_' + field)(value))
87     def full_callback(option, opt_str, value, parser):
88         ne = utils.parse_name_email(value)
89         if not ne:
90             raise optparse.OptionValueError(
91                 'Bad %s specification: %r' % (opt_str, value))
92         name, email = ne
93         short_callback(option, opt_str, name, parser, 'name')
94         short_callback(option, opt_str, email, parser, 'email')
95     return ([optparse.make_option(
96                 '--%s' % person, metavar = '"NAME <EMAIL>"', type = 'string',
97                 action = 'callback', callback = full_callback, dest = person,
98                 default = lambda p: p, help = 'set the %s details' % person)]
99             + [optparse.make_option(
100                 '--%s%s' % (short, f), metavar = f.upper(), type = 'string',
101                 action = 'callback', callback = short_callback, dest = person,
102                 callback_args = (f,), help = 'set the %s %s' % (person, f))
103                for f in ['name', 'email', 'date']])
104
105 def author_committer_options():
106     return person_opts('author', 'auth') + person_opts('committer', 'comm')