This refactoring is specific to the new infrastructure, so only new and edit use it currently, but other commands can start using it as they are converted. Signed-off-by: Karl Hasselström <kha@xxxxxxxxxxx> --- stgit/commands/common.py | 33 ++++++++++-------------------- stgit/commands/edit.py | 25 +++-------------------- stgit/commands/new.py | 40 ++++++++++--------------------------- stgit/utils.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 73 deletions(-) diff --git a/stgit/commands/common.py b/stgit/commands/common.py index 5a1952b..d6df813 100644 --- a/stgit/commands/common.py +++ b/stgit/commands/common.py @@ -266,30 +266,19 @@ def parse_patches(patch_args, patch_list, boundary = 0, ordered = False): return patches def name_email(address): - """Return a tuple consisting of the name and email parsed from a - standard 'name <email>' or 'email (name)' string - """ - address = re.sub(r'[\\"]', r'\\\g<0>', address) - str_list = re.findall('^(.*)\s*<(.*)>\s*$', address) - if not str_list: - str_list = re.findall('^(.*)\s*\((.*)\)\s*$', address) - if not str_list: - raise CmdException('Incorrect "name <email>"/"email (name)"' - ' string: %s' % address) - return ( str_list[0][1], str_list[0][0] ) - - return str_list[0] + p = parse_name_email(address) + if p: + return p + else: + raise CmdException('Incorrect "name <email>"/"email (name)" string: %s' + % address) def name_email_date(address): - """Return a tuple consisting of the name, email and date parsed - from a 'name <email> date' string - """ - address = re.sub(r'[\\"]', r'\\\g<0>', address) - str_list = re.findall('^(.*)\s*<(.*)>\s*(.*)\s*$', address) - if not str_list: - raise CmdException, 'Incorrect "name <email> date" string: %s' % address - - return str_list[0] + p = parse_name_email_date(address) + if p: + return p + else: + raise CmdException('Incorrect "name <email> date" string: %s' % address) def address_or_alias(addr_str): """Return the address if it contains an e-mail address or look up diff --git a/stgit/commands/edit.py b/stgit/commands/edit.py index 7daf156..037425b 100644 --- a/stgit/commands/edit.py +++ b/stgit/commands/edit.py @@ -60,19 +60,8 @@ options = [make_option('-d', '--diff', action = 'store_true'), make_option('-e', '--edit', action = 'store_true', help = 'invoke interactive editor'), - make_option('--author', metavar = '"NAME <EMAIL>"', - help = 'replae the author details with "NAME <EMAIL>"'), - make_option('--authname', - help = 'replace the author name with AUTHNAME'), - make_option('--authemail', - help = 'replace the author e-mail with AUTHEMAIL'), - make_option('--authdate', - help = 'replace the author date with AUTHDATE'), - make_option('--commname', - help = 'replace the committer name with COMMNAME'), - make_option('--commemail', - help = 'replace the committer e-mail with COMMEMAIL') ] + (utils.make_sign_options() + utils.make_message_options() + + utils.make_author_committer_options() + utils.make_diff_opts_option()) def patch_diff(repository, cd, diff, diff_flags): @@ -141,16 +130,8 @@ def func(parser, options, args): options.message) # Modify author and committer data. - if options.author != None: - options.authname, options.authemail = common.name_email(options.author) - for p, f, val in [('author', 'name', options.authname), - ('author', 'email', options.authemail), - ('author', 'date', gitlib.Date.maybe(options.authdate)), - ('committer', 'name', options.commname), - ('committer', 'email', options.commemail)]: - if val != None: - cd = getattr(cd, 'set_' + p)( - getattr(getattr(cd, p), 'set_' + f)(val)) + cd = (cd.set_author(options.author(cd.author)) + .set_committer(options.committer(cd.committer))) # Add Signed-off-by: or similar. if options.sign_str != None: diff --git a/stgit/commands/new.py b/stgit/commands/new.py index dd9f93e..d44b8cc 100644 --- a/stgit/commands/new.py +++ b/stgit/commands/new.py @@ -39,19 +39,8 @@ line of the commit message.""" directory = common.DirectoryHasRepositoryLib() options = [make_option('-m', '--message', help = 'use MESSAGE as the patch description'), - make_option('-a', '--author', metavar = '"NAME <EMAIL>"', - help = 'use "NAME <EMAIL>" as the author details'), - make_option('--authname', - help = 'use AUTHNAME as the author name'), - make_option('--authemail', - help = 'use AUTHEMAIL as the author e-mail'), - make_option('--authdate', - help = 'use AUTHDATE as the author date'), - make_option('--commname', - help = 'use COMMNAME as the committer name'), - make_option('--commemail', - help = 'use COMMEMAIL as the committer e-mail') - ] + utils.make_sign_options() + ] + (utils.make_author_committer_options() + + utils.make_sign_options()) def func(parser, options, args): """Create a new patch.""" @@ -72,30 +61,23 @@ def func(parser, options, args): parser.error('incorrect number of arguments') head = directory.repository.refs.get(directory.repository.head) - cd = gitlib.Commitdata(tree = head.data.tree, parents = [head], - message = '') + cd = gitlib.Commitdata( + tree = head.data.tree, parents = [head], message = '', + author = gitlib.Person.author(), committer = gitlib.Person.committer()) # Set patch commit message from commandline. if options.message != None: cd = cd.set_message(options.message) - # Specify author and committer data. - if options.author != None: - options.authname, options.authemail = common.name_email(options.author) - for p, f, val in [('author', 'name', options.authname), - ('author', 'email', options.authemail), - ('author', 'date', gitlib.Date.maybe(options.authdate)), - ('committer', 'name', options.commname), - ('committer', 'email', options.commemail)]: - if val != None: - cd = getattr(cd, 'set_' + p)( - getattr(getattr(cd, p), 'set_' + f)(val)) + # Modify author and committer data. + cd = (cd.set_author(options.author(cd.author)) + .set_committer(options.committer(cd.committer))) # Add Signed-off-by: or similar. if options.sign_str != None: - cd = cd.set_message(utils.add_sign_line( - cd.message, options.sign_str, gitlib.Person.committer().name, - gitlib.Person.committer().email)) + cd = cd.set_message( + utils.add_sign_line(cd.message, options.sign_str, + cd.committer.name, cd.committer.email)) # Let user edit the commit message manually. if not options.message: diff --git a/stgit/utils.py b/stgit/utils.py index b75c3b4..947f747 100644 --- a/stgit/utils.py +++ b/stgit/utils.py @@ -322,6 +322,56 @@ def make_diff_opts_option(): 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 <email>' or 'email (name)' string.""" + address = re.sub(r'[\\"]', r'\\\g<0>', address) + str_list = re.findall(r'^(.*)\s*<(.*)>\s*$', address) + if not str_list: + str_list = re.findall(r'^(.*)\s*\((.*)\)\s*$', address) + if not str_list: + return None + return (str_list[0][1], str_list[0][0]) + return str_list[0] + +def parse_name_email_date(address): + """Return a tuple consisting of the name, email and date parsed + from a 'name <email> date' string.""" + address = re.sub(r'[\\"]', r'\\\g<0>', address) + str_list = re.findall('^(.*)\s*<(.*)>\s*(.*)\s*$', address) + if not str_list: + return None + return str_list[0] + +def make_person_options(person, short): + """Sets options.<person> 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 <EMAIL>"', 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 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html