From: Karl Hasselström Date: Sat, 6 Sep 2008 08:16:22 +0000 (+0200) Subject: Refactoring: move shared options to their own module X-Git-Tag: v0.15-rc1~161 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/stgit/commitdiff_plain/20a52e06c7e0b8da714aec725b32ed8722f79c35?ds=inline Refactoring: move shared options to their own module Signed-off-by: Karl Hasselström --- diff --git a/stgit/argparse.py b/stgit/argparse.py new file mode 100644 index 0000000..4999272 --- /dev/null +++ b/stgit/argparse.py @@ -0,0 +1,106 @@ +"""Utility functions for command-line option parsing.""" + +import optparse, sys +from stgit import utils +from stgit.config import config + +def sign_options(): + def callback(option, opt_str, value, parser, sign_str): + if parser.values.sign_str not in [None, sign_str]: + raise optparse.OptionValueError( + '--ack and --sign were both specified') + parser.values.sign_str = sign_str + return [optparse.make_option('--sign', action = 'callback', + callback = callback, dest = 'sign_str', + callback_args = ('Signed-off-by',), + help = 'add Signed-off-by line'), + optparse.make_option('--ack', action = 'callback', + callback = callback, dest = 'sign_str', + callback_args = ('Acked-by',), + help = 'add Acked-by line')] + +def message_options(): + def no_dup(parser): + if parser.values.message != None: + raise optparse.OptionValueError( + 'Cannot give more than one --message or --file') + def no_combine(parser): + if (parser.values.message != None + and parser.values.save_template != None): + raise optparse.OptionValueError( + 'Cannot give both --message/--file and --save-template') + def msg_callback(option, opt_str, value, parser): + no_dup(parser) + parser.values.message = value + no_combine(parser) + def file_callback(option, opt_str, value, parser): + no_dup(parser) + if value == '-': + parser.values.message = sys.stdin.read() + else: + f = file(value) + parser.values.message = f.read() + f.close() + no_combine(parser) + def templ_callback(option, opt_str, value, parser): + if value == '-': + def w(s): + sys.stdout.write(s) + else: + def w(s): + f = file(value, 'w+') + f.write(s) + f.close() + parser.values.save_template = w + no_combine(parser) + m = optparse.make_option + return [m('-m', '--message', action = 'callback', callback = msg_callback, + dest = 'message', type = 'string', + help = 'use MESSAGE instead of invoking the editor'), + m('-f', '--file', action = 'callback', callback = file_callback, + dest = 'message', type = 'string', metavar = 'FILE', + help = 'use FILE instead of invoking the editor'), + m('--save-template', action = 'callback', callback = templ_callback, + metavar = 'FILE', dest = 'save_template', type = 'string', + help = 'save the message template to FILE and exit')] + +def diff_opts_option(): + def diff_opts_callback(option, opt_str, value, parser): + if value: + parser.values.diff_flags.extend(value.split()) + else: + parser.values.diff_flags = [] + return [optparse.make_option( + '-O', '--diff-opts', dest = 'diff_flags', + default = (config.get('stgit.diff-opts') or '').split(), + action = 'callback', callback = diff_opts_callback, + type = 'string', metavar = 'OPTIONS', + help = 'extra options to pass to "git diff"')] + +def person_opts(person, short): + """Sets options. to a function that modifies a Person + according to the commandline options.""" + def short_callback(option, opt_str, value, parser, field): + f = getattr(parser.values, person) + setattr(parser.values, person, + lambda p: getattr(f(p), 'set_' + field)(value)) + def full_callback(option, opt_str, value, parser): + ne = utils.parse_name_email(value) + if not ne: + raise optparse.OptionValueError( + 'Bad %s specification: %r' % (opt_str, value)) + name, email = ne + short_callback(option, opt_str, name, parser, 'name') + short_callback(option, opt_str, email, parser, 'email') + return ([optparse.make_option( + '--%s' % person, metavar = '"NAME "', type = 'string', + action = 'callback', callback = full_callback, dest = person, + default = lambda p: p, help = 'set the %s details' % person)] + + [optparse.make_option( + '--%s%s' % (short, f), metavar = f.upper(), type = 'string', + action = 'callback', callback = short_callback, dest = person, + callback_args = (f,), help = 'set the %s %s' % (person, f)) + for f in ['name', 'email', 'date']]) + +def author_committer_options(): + return person_opts('author', 'auth') + person_opts('committer', 'comm') diff --git a/stgit/commands/coalesce.py b/stgit/commands/coalesce.py index 1a34934..2d672bb 100644 --- a/stgit/commands/coalesce.py +++ b/stgit/commands/coalesce.py @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from optparse import make_option from stgit.out import * -from stgit import utils +from stgit import argparse, utils from stgit.commands import common from stgit.lib import git, transaction @@ -35,7 +35,7 @@ done a sequence of pushes and pops yourself.""" directory = common.DirectoryHasRepositoryLib() options = [make_option('-n', '--name', help = 'name of coalesced patch') - ] + utils.make_message_options() + ] + argparse.message_options() class SaveTemplateDone(Exception): pass diff --git a/stgit/commands/diff.py b/stgit/commands/diff.py index 1237c85..4f3e2c4 100644 --- a/stgit/commands/diff.py +++ b/stgit/commands/diff.py @@ -23,8 +23,7 @@ from pydoc import pager from stgit.commands.common import * from stgit.utils import * from stgit.out import * -from stgit import stack, git - +from stgit import argparse, stack, git help = 'show the tree diff' usage = """%prog [options] [] @@ -46,7 +45,7 @@ options = [make_option('-r', '--range', make_option('-s', '--stat', help = 'show the stat instead of the diff', action = 'store_true') - ] + make_diff_opts_option() + ] + argparse.diff_opts_option() def func(parser, options, args): """Show the tree diff diff --git a/stgit/commands/edit.py b/stgit/commands/edit.py index 3b36a6c..92447a8 100644 --- a/stgit/commands/edit.py +++ b/stgit/commands/edit.py @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from optparse import make_option -from stgit import git, utils +from stgit import argparse, git, utils from stgit.commands import common from stgit.lib import git as gitlib, transaction from stgit.out import * @@ -60,9 +60,9 @@ options = [make_option('-d', '--diff', action = 'store_true'), make_option('-e', '--edit', action = 'store_true', help = 'invoke interactive editor'), - ] + (utils.make_sign_options() + utils.make_message_options() - + utils.make_author_committer_options() - + utils.make_diff_opts_option()) + ] + (argparse.sign_options() + argparse.message_options() + + argparse.author_committer_options() + + argparse.diff_opts_option()) def patch_diff(repository, cd, diff, diff_flags): if diff: diff --git a/stgit/commands/export.py b/stgit/commands/export.py index 183a1b5..fb373a9 100644 --- a/stgit/commands/export.py +++ b/stgit/commands/export.py @@ -22,7 +22,7 @@ import os from optparse import make_option from stgit.commands import common -from stgit import git, utils, templates +from stgit import argparse, git, templates from stgit.out import out from stgit.lib import git as gitlib @@ -66,7 +66,7 @@ options = [make_option('-d', '--dir', make_option('-s', '--stdout', help = 'dump the patches to the standard output', action = 'store_true') - ] + utils.make_diff_opts_option() + ] + argparse.diff_opts_option() def func(parser, options, args): """Export a range of patches. diff --git a/stgit/commands/files.py b/stgit/commands/files.py index d240872..cdb0b52 100644 --- a/stgit/commands/files.py +++ b/stgit/commands/files.py @@ -22,8 +22,7 @@ from optparse import OptionParser, make_option from stgit.commands.common import * from stgit.utils import * from stgit.out import * -from stgit import stack, git - +from stgit import argparse, stack, git help = 'show the files modified by a patch (or the current patch)' usage = """%prog [options] [[:]] @@ -41,8 +40,7 @@ options = [make_option('-s', '--stat', make_option('--bare', help = 'bare file names (useful for scripting)', action = 'store_true') - ] + make_diff_opts_option() - + ] + argparse.diff_opts_option() def func(parser, options, args): """Show the files modified by a patch (or the current patch) diff --git a/stgit/commands/imprt.py b/stgit/commands/imprt.py index 227743f..e649ed7 100644 --- a/stgit/commands/imprt.py +++ b/stgit/commands/imprt.py @@ -23,8 +23,7 @@ from optparse import OptionParser, make_option from stgit.commands.common import * from stgit.utils import * from stgit.out import * -from stgit import stack, git - +from stgit import argparse, stack, git help = 'import a GNU diff file as a new patch' usage = """%prog [options] [|] @@ -88,7 +87,7 @@ options = [make_option('-m', '--mail', help = 'use COMMNAME as the committer name'), make_option('--commemail', help = 'use COMMEMAIL as the committer e-mail') - ] + make_sign_options() + ] + argparse.sign_options() def __strip_patch_name(name): diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py index 4e7ed2f..521c8eb 100644 --- a/stgit/commands/mail.py +++ b/stgit/commands/mail.py @@ -22,7 +22,7 @@ from optparse import OptionParser, make_option from stgit.commands.common import * from stgit.utils import * from stgit.out import * -from stgit import stack, git, version, templates +from stgit import argparse, stack, git, version, templates from stgit.config import config from stgit.run import Run @@ -151,8 +151,7 @@ options = [make_option('-a', '--all', make_option('-m', '--mbox', help = 'generate an mbox file instead of sending', action = 'store_true') - ] + make_diff_opts_option() - + ] + argparse.diff_opts_option() def __get_sender(): """Return the 'authname ' string as read from the diff --git a/stgit/commands/new.py b/stgit/commands/new.py index c4ee4e1..eb45e1b 100644 --- a/stgit/commands/new.py +++ b/stgit/commands/new.py @@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from optparse import make_option -from stgit import utils +from stgit import argparse, utils from stgit.commands import common from stgit.lib import git as gitlib, transaction @@ -37,8 +37,8 @@ If no name is given for the new patch, one is generated from the first line of the commit message.""" directory = common.DirectoryHasRepositoryLib() -options = (utils.make_author_committer_options() - + utils.make_message_options() + utils.make_sign_options()) +options = (argparse.author_committer_options() + + argparse.message_options() + argparse.sign_options()) def func(parser, options, args): """Create a new patch.""" diff --git a/stgit/commands/show.py b/stgit/commands/show.py index b77a9c8..36361d6 100644 --- a/stgit/commands/show.py +++ b/stgit/commands/show.py @@ -20,8 +20,7 @@ from optparse import OptionParser, make_option from pydoc import pager from stgit.commands.common import * -from stgit import git - +from stgit import argparse, git help = 'show the commit corresponding to a patch (or the current patch)' usage = """%prog [options] [] [] [..] @@ -39,8 +38,7 @@ options = [make_option('-b', '--branch', make_option('-u', '--unapplied', help = 'show the unapplied patches', action = 'store_true') - ] + make_diff_opts_option() - + ] + argparse.diff_opts_option() def func(parser, options, args): """Show commit log and diff diff --git a/stgit/utils.py b/stgit/utils.py index 864975d..979fd3b 100644 --- a/stgit/utils.py +++ b/stgit/utils.py @@ -1,7 +1,7 @@ """Common utility functions """ -import errno, optparse, os, os.path, re, sys +import errno, os, os.path, re, sys from stgit.exception import * from stgit.config import config from stgit.out import * @@ -238,21 +238,6 @@ if not 'all' in dir(__builtins__): return False return True -def make_sign_options(): - def callback(option, opt_str, value, parser, sign_str): - if parser.values.sign_str not in [None, sign_str]: - raise optparse.OptionValueError( - '--ack and --sign were both specified') - parser.values.sign_str = sign_str - return [optparse.make_option('--sign', action = 'callback', - callback = callback, dest = 'sign_str', - callback_args = ('Signed-off-by',), - help = 'add Signed-off-by line'), - optparse.make_option('--ack', action = 'callback', - callback = callback, dest = 'sign_str', - callback_args = ('Acked-by',), - help = 'add Acked-by line')] - def add_sign_line(desc, sign_str, name, email): if not sign_str: return desc @@ -264,64 +249,6 @@ def add_sign_line(desc, sign_str, name, email): desc = desc + '\n' return '%s\n%s\n' % (desc, sign_str) -def make_message_options(): - def no_dup(parser): - if parser.values.message != None: - raise optparse.OptionValueError( - 'Cannot give more than one --message or --file') - def no_combine(parser): - if (parser.values.message != None - and parser.values.save_template != None): - raise optparse.OptionValueError( - 'Cannot give both --message/--file and --save-template') - def msg_callback(option, opt_str, value, parser): - no_dup(parser) - parser.values.message = value - no_combine(parser) - def file_callback(option, opt_str, value, parser): - no_dup(parser) - if value == '-': - parser.values.message = sys.stdin.read() - else: - f = file(value) - parser.values.message = f.read() - f.close() - no_combine(parser) - def templ_callback(option, opt_str, value, parser): - if value == '-': - def w(s): - sys.stdout.write(s) - else: - def w(s): - f = file(value, 'w+') - f.write(s) - f.close() - parser.values.save_template = w - no_combine(parser) - m = optparse.make_option - return [m('-m', '--message', action = 'callback', callback = msg_callback, - dest = 'message', type = 'string', - help = 'use MESSAGE instead of invoking the editor'), - m('-f', '--file', action = 'callback', callback = file_callback, - dest = 'message', type = 'string', metavar = 'FILE', - help = 'use FILE instead of invoking the editor'), - m('--save-template', action = 'callback', callback = templ_callback, - metavar = 'FILE', dest = 'save_template', type = 'string', - help = 'save the message template to FILE and exit')] - -def make_diff_opts_option(): - def diff_opts_callback(option, opt_str, value, parser): - if value: - parser.values.diff_flags.extend(value.split()) - else: - parser.values.diff_flags = [] - return [optparse.make_option( - '-O', '--diff-opts', dest = 'diff_flags', - default = (config.get('stgit.diff-opts') or '').split(), - action = 'callback', callback = diff_opts_callback, - type = 'string', metavar = 'OPTIONS', - help = 'extra options to pass to "git diff"')] - def parse_name_email(address): """Return a tuple consisting of the name and email parsed from a standard 'name ' or 'email (name)' string.""" @@ -343,35 +270,6 @@ def parse_name_email_date(address): return None return str_list[0] -def make_person_options(person, short): - """Sets options. to a function that modifies a Person - according to the commandline options.""" - def short_callback(option, opt_str, value, parser, field): - f = getattr(parser.values, person) - setattr(parser.values, person, - lambda p: getattr(f(p), 'set_' + field)(value)) - def full_callback(option, opt_str, value, parser): - ne = parse_name_email(value) - if not ne: - raise optparse.OptionValueError( - 'Bad %s specification: %r' % (opt_str, value)) - name, email = ne - short_callback(option, opt_str, name, parser, 'name') - short_callback(option, opt_str, email, parser, 'email') - return ([optparse.make_option( - '--%s' % person, metavar = '"NAME "', type = 'string', - action = 'callback', callback = full_callback, dest = person, - default = lambda p: p, help = 'set the %s details' % person)] - + [optparse.make_option( - '--%s%s' % (short, f), metavar = f.upper(), type = 'string', - action = 'callback', callback = short_callback, dest = person, - callback_args = (f,), help = 'set the %s %s' % (person, f)) - for f in ['name', 'email', 'date']]) - -def make_author_committer_options(): - return (make_person_options('author', 'auth') - + make_person_options('committer', 'comm')) - # Exit codes. STGIT_SUCCESS = 0 # everything's OK STGIT_GENERAL_ERROR = 1 # seems to be non-command-specific error