try:
sender = str(git.user())
except git.GitException:
- sender = str(git.author())
-
+ try:
+ sender = str(git.author())
+ except git.GitException:
+ pass
if not sender:
- raise CmdException, 'unknown sender details'
+ raise CmdException, ('Unknown sender name and e-mail; you should'
+ ' for example set git config user.name and'
+ ' user.email')
+ sender = email.Utils.parseaddr(sender)
- return address_or_alias(sender)
+ return email.Utils.formataddr(address_or_alias(sender))
+
+def __addr_list(msg, header):
+ return [addr for name, addr in
+ email.Utils.getaddresses(msg.get_all(header, []))]
def __parse_addresses(msg):
"""Return a two elements tuple: (from, [to])
"""
- def __addr_list(msg, header):
- return [name_addr[1] for name_addr in
- email.Utils.getaddresses(msg.get_all(header, []))]
-
from_addr_list = __addr_list(msg, 'From')
if len(from_addr_list) == 0:
raise CmdException, 'No "From" address'
if len(to_addr_list) == 0:
raise CmdException, 'No "To/Cc/Bcc" addresses'
- return (from_addr_list[0], to_addr_list)
+ return (from_addr_list[0], set(to_addr_list))
def __send_message_sendmail(sendmail, msg):
"""Send the message using the sendmail command.
"""Build the address headers and check existing headers in the
template.
"""
- def __replace_header(header, addr):
- if addr:
- crt_addr = msg[header]
- del msg[header]
-
- if crt_addr:
- msg[header] = address_or_alias(', '.join([crt_addr, addr]))
- else:
- msg[header] = address_or_alias(addr)
+ def __addr_pairs(msg, header, extra):
+ pairs = email.Utils.getaddresses(msg.get_all(header, []) + extra)
+ # remove pairs without an address and resolve the aliases
+ return [address_or_alias(p) for p in pairs if p[1]]
+
+ def __update_header(header, addr = '', ignore = ()):
+ addr_pairs = __addr_pairs(msg, header, [addr])
+ del msg[header]
+ # remove the duplicates and filter the addresses
+ addr_dict = dict((addr, email.Utils.formataddr((name, addr)))
+ for name, addr in addr_pairs if addr not in ignore)
+ if addr_dict:
+ msg[header] = ', '.join(addr_dict.itervalues())
+ return set(addr_dict.iterkeys())
to_addr = ''
cc_addr = ''
+ extra_cc_addr = ''
bcc_addr = ''
autobcc = config.get('stgit.autobcc') or ''
if options.to:
to_addr = ', '.join(options.to)
if options.cc:
- cc_addr = ', '.join(options.cc + extra_cc)
- cc_addr = ', '.join(options.cc + extra_cc)
- elif extra_cc:
- cc_addr = ', '.join(extra_cc)
+ cc_addr = ', '.join(options.cc)
+ if extra_cc:
+ extra_cc_addr = ', '.join(extra_cc)
if options.bcc:
bcc_addr = ', '.join(options.bcc + [autobcc])
elif autobcc:
bcc_addr = autobcc
- __replace_header('To', to_addr)
- __replace_header('Cc', cc_addr)
- __replace_header('Bcc', bcc_addr)
+ # if an address is on a header, ignore it from the rest
+ to_set = __update_header('To', to_addr)
+ cc_set = __update_header('Cc', cc_addr, to_set)
+ bcc_set = __update_header('Bcc', bcc_addr, to_set.union(cc_set))
+
+ # --auto generated addresses, don't include the sender
+ from_set = __update_header('From')
+ __update_header('Cc', extra_cc_addr, to_set.union(bcc_set).union(from_set))
+
+ # update other address headers
+ __update_header('Reply-To')
+ __update_header('Mail-Reply-To')
+ __update_header('Mail-Followup-To')
def __get_signers_list(msg):
"""Return the address list generated from signed-off-by and
acked-by lines in the message.
"""
addr_list = []
-
- r = re.compile('^(signed-off-by|acked-by|cc):\s+(.+)$', re.I)
+ tags = '%s|%s|%s|%s|%s|%s|%s' % (
+ 'signed-off-by',
+ 'acked-by',
+ 'cc',
+ 'reviewed-by',
+ 'reported-by',
+ 'tested-by',
+ 'reported-and-tested-by')
+ regex = '^(%s):\s+(.+)$' % tags
+
+ r = re.compile(regex, re.I)
for line in msg.split('\n'):
m = r.match(line)
if m:
ref_id = '<%s>' % ref_id.strip(' \t\n<>')
msg['In-Reply-To'] = ref_id
msg['References'] = ref_id
- msg['User-Agent'] = 'StGIT/%s' % version.version
+ msg['User-Agent'] = 'StGit/%s' % version.version
def __encode_message(msg):
# 7 or 8 bit encoding
for p in patches),
'diffstat': gitlib.diffstat(git.diff(
rev1 = git_id(crt_series, '%s^' % patches[0]),
- rev2 = git_id(crt_series, '%s' % patches[-1])))}
+ rev2 = git_id(crt_series, '%s' % patches[-1]),
+ diff_flags = options.diff_flags))}
try:
msg_string = tmpl % tmpl_dict
else:
raise CmdException, 'Incorrect options. Unknown patches to send'
+ # early test for sender identity
+ __get_sender()
+
out.start('Checking the validity of the patches')
for p in patches:
if crt_series.empty_patch(p):