X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/5f1629be6d0d10aa2acb253c89c6f6c38fdf3cf2..003753379ff42f2c7d1a69cd1b77b95384f19ea2:/stgit/commands/imprt.py diff --git a/stgit/commands/imprt.py b/stgit/commands/imprt.py index 98fe708..1c21a74 100644 --- a/stgit/commands/imprt.py +++ b/stgit/commands/imprt.py @@ -16,13 +16,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ import sys, os, re, email -from email.Header import decode_header, make_header from mailbox import UnixMailbox from StringIO import StringIO from optparse import OptionParser, make_option from stgit.commands.common import * from stgit.utils import * +from stgit.out import * from stgit import stack, git @@ -44,6 +44,7 @@ stack. The patch description has to be separated from the data with a '---' line.""" +directory = DirectoryHasRepository() options = [make_option('-m', '--mail', help = 'import the patch from a standard e-mail file', action = 'store_true'), @@ -86,13 +87,10 @@ options = [make_option('-m', '--mail', make_option('--commname', help = 'use COMMNAME as the committer name'), make_option('--commemail', - help = 'use COMMEMAIL as the committer e-mail')] + help = 'use COMMEMAIL as the committer e-mail') + ] + make_sign_options() -def __end_descr(line): - return re.match('---\s*$', line) or re.match('diff -', line) or \ - re.match('Index: ', line) - def __strip_patch_name(name): stripped = re.sub('^[0-9]+-(.*)$', '\g<1>', name) stripped = re.sub('^(.*)\.(diff|patch)$', '\g<1>', stripped) @@ -104,127 +102,6 @@ def __replace_slashes_with_dashes(name): return stripped -def __split_descr_diff(string): - """Return the description and the diff from the given string - """ - descr = diff = '' - top = True - - for line in string.split('\n'): - if top: - if not __end_descr(line): - descr += line + '\n' - continue - else: - top = False - diff += line + '\n' - - return (descr.rstrip(), diff) - -def __parse_description(descr): - """Parse the patch description and return the new description and - author information (if any). - """ - subject = body = '' - authname = authemail = authdate = None - - descr_lines = [line.rstrip() for line in descr.split('\n')] - if not descr_lines: - raise CmdException, "Empty patch description" - - lasthdr = 0 - end = len(descr_lines) - - # Parse the patch header - for pos in range(0, end): - if not descr_lines[pos]: - continue - # check for a "From|Author:" line - if re.match('\s*(?:from|author):\s+', descr_lines[pos], re.I): - auth = re.findall('^.*?:\s+(.*)$', descr_lines[pos])[0] - authname, authemail = name_email(auth) - lasthdr = pos + 1 - continue - # check for a "Date:" line - if re.match('\s*date:\s+', descr_lines[pos], re.I): - authdate = re.findall('^.*?:\s+(.*)$', descr_lines[pos])[0] - lasthdr = pos + 1 - continue - if subject: - break - # get the subject - subject = descr_lines[pos] - lasthdr = pos + 1 - - # get the body - if lasthdr < end: - body = reduce(lambda x, y: x + '\n' + y, descr_lines[lasthdr:], '') - - return (subject + body, authname, authemail, authdate) - -def __parse_mail(msg): - """Parse the message object and return (description, authname, - authemail, authdate, diff) - """ - def __decode_header(header): - """Decode a qp-encoded e-mail header as per rfc2047""" - try: - words_enc = decode_header(header) - hobj = make_header(words_enc) - except Exception, ex: - raise CmdException, 'header decoding error: %s' % str(ex) - return unicode(hobj).encode('utf-8') - - # parse the headers - if msg.has_key('from'): - authname, authemail = name_email(__decode_header(msg['from'])) - else: - authname = authemail = None - - # '\n\t' can be found on multi-line headers - descr = __decode_header(msg['subject']).replace('\n\t', ' ') - authdate = msg['date'] - - # remove the '[*PATCH*]' expression in the subject - if descr: - descr = re.findall('^(\[.*?[Pp][Aa][Tt][Cc][Hh].*?\])?\s*(.*)$', - descr)[0][1] - else: - raise CmdException, 'Subject: line not found' - - # the rest of the message - msg_text = '' - for part in msg.walk(): - if part.get_content_type() == 'text/plain': - msg_text += part.get_payload(decode = True) - - rem_descr, diff = __split_descr_diff(msg_text) - if rem_descr: - descr += '\n\n' + rem_descr - - # parse the description for author information - descr, descr_authname, descr_authemail, descr_authdate = \ - __parse_description(descr) - if descr_authname: - authname = descr_authname - if descr_authemail: - authemail = descr_authemail - if descr_authdate: - authdate = descr_authdate - - return (descr, authname, authemail, authdate, diff) - -def __parse_patch(fobj): - """Parse the input file and return (description, authname, - authemail, authdate, diff) - """ - descr, diff = __split_descr_diff(fobj.read()) - descr, authname, authemail, authdate = __parse_description(descr) - - # we don't yet have an agreed place for the creation date. - # Just return None - return (descr, authname, authemail, authdate, diff) - def __create_patch(filename, message, author_name, author_email, author_date, diff, options): """Create a new patch on the stack @@ -252,7 +129,7 @@ def __create_patch(filename, message, author_name, author_email, out.info('Ignoring already applied patch "%s"' % patch) return if options.replace and patch in crt_series.get_unapplied(): - crt_series.delete_patch(patch) + crt_series.delete_patch(patch, keep_log = True) # refresh_patch() will invoke the editor in this case, with correct # patch content @@ -288,11 +165,14 @@ def __create_patch(filename, message, author_name, author_email, else: out.start('Importing patch "%s"' % patch) if options.base: - git.apply_patch(diff = diff, base = git_id(options.base)) + git.apply_patch(diff = diff, + base = git_id(crt_series, options.base)) else: git.apply_patch(diff = diff) crt_series.refresh_patch(edit = options.edit, - show_patch = options.showpatch) + show_patch = options.showpatch, + sign_str = options.sign_str, + backup = False) out.done() def __import_file(filename, options, patch = None): @@ -309,10 +189,10 @@ def __import_file(filename, options, patch = None): except Exception, ex: raise CmdException, 'error parsing the e-mail file: %s' % str(ex) message, author_name, author_email, author_date, diff = \ - __parse_mail(msg) + parse_mail(msg) else: message, author_name, author_email, author_date, diff = \ - __parse_patch(f) + parse_patch(f) if filename: f.close() @@ -364,7 +244,7 @@ def __import_mbox(filename, options): for msg in mbox: message, author_name, author_email, author_date, diff = \ - __parse_mail(msg) + parse_mail(msg) __create_patch(None, message, author_name, author_email, author_date, diff, options) @@ -392,7 +272,7 @@ def func(parser, options, args): check_local_changes() check_conflicts() - check_head_top_equal() + check_head_top_equal(crt_series) if len(args) == 1: filename = args[0] @@ -408,4 +288,4 @@ def func(parser, options, args): else: __import_file(filename, options) - print_crt_patch() + print_crt_patch(crt_series)