Mercurial > hg > pyhgsh
annotate hgext/patchbomb.py @ 1871:258e3a7955b8
patchbomb: ignore exception if pager quits.
author  Vadim Gelfer <vadim.gelfer@gmail.com> 

date  Thu, 09 Mar 2006 16:26:49 0800 
parents  4d2791f4ef80 
children  d821918e3bee 
rev  line source 

1669
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

1 # Command for sending a collection of Mercurial changesets as a series 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

2 # of patch emails. 
875  3 # 
4 # The series is started off with a "[PATCH 0 of N]" introduction,  
5 # which describes the series as a whole.  
6 #  
7 # Each patch email has a Subject line of "[PATCH M of N] ...", using  
8 # the first line of the changeset description as the subject text.  
9 # The message contains two or three body parts:  
10 #  
11 # The remainder of the changeset description.  
12 #  
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

13 # [Optional] If the diffstat program is installed, the result of 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

14 # running diffstat on the patch. 
875  15 # 
16 # The patch itself, as generated by "hg export".  
17 #  
18 # Each message refers to all of its predecessors using the InReplyTo  
19 # and References headers, so they will show up as a sequence in  
20 # threaded mail and news readers, and in mail archives.  
21 #  
22 # For each changeset, you will be prompted with a diffstat summary and  
23 # the changeset summary, so you can be sure you are sending the right  
24 # changes.  
25 #  
26 # It is best to run this script with the "n" (test only) flag before  
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

27 # firing it up "for real", in which case it will use your pager to 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

28 # display each of the messages that it would send. 
875  29 # 
1702
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

30 # The "m" (mbox) option will create an mbox file instead of sending 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

31 # the messages directly. This can be reviewed e.g. with "mutt R f mbox", 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

32 # and finally sent with "formail s sendmail bm t < mbox". 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

33 # 
875  34 # To configure a default mail host, add a section like this to your 
35 # hgrc file:  
36 #  
37 # [smtp]  
38 # host = my_mail_host  
39 # port = 1025  
1226
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

40 # tls = yes # or omit if not needed 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

41 # username = user # if SMTP authentication required 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

42 # password = password # if SMTP authentication required  PLAINTEXT 
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

43 # 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

44 # To configure other defaults, add a section like this to your hgrc 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

45 # file: 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

46 # 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

47 # [patchbomb] 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

48 # from = My Name <my@email> 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

49 # to = recipient1, recipient2, ... 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

50 # cc = cc1, cc2, ... 
875  51 
1827
26dd4ae77b7b
get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents:
1702
diff
changeset

52 from mercurial.demandload import * 
26dd4ae77b7b
get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents:
1702
diff
changeset

53 demandload(globals(), '''email.MIMEMultipart email.MIMEText email.Utils 
26dd4ae77b7b
get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents:
1702
diff
changeset

54 mercurial:commands,hg,ui 
1871
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset

55 os errno popen2 smtplib socket sys tempfile time''') 
1671
ba30c17d55f6
forgot to add import statement for _.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

56 from mercurial.i18n import gettext as _ 
875  57 
1204
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset

58 try: 
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset

59 # readline gives raw_input editing capabilities, but is not 
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset

60 # present on windows 
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset

61 import readline 
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset

62 except ImportError: pass 
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset

63 
875  64 def diffstat(patch): 
65 fd, name = tempfile.mkstemp()  
66 try:  
67 p = popen2.Popen3('diffstat p1 w79 2>/dev/null > ' + name)  
68 try:  
69 for line in patch: print >> p.tochild, line  
70 p.tochild.close()  
71 if p.wait(): return  
72 fp = os.fdopen(fd, 'r')  
73 stat = []  
74 for line in fp: stat.append(line.lstrip())  
75 last = stat.pop()  
76 stat.insert(0, last)  
77 stat = ''.join(stat)  
78 if stat.startswith('0 files'): raise ValueError  
79 return stat  
80 except: raise  
81 finally:  
82 try: os.unlink(name)  
83 except: pass  
84  
85 def patchbomb(ui, repo, *revs, **opts):  
1672
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

86 '''send changesets as a series of patch emails 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

87 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

88 The series starts with a "[PATCH 0 of N]" introduction, which 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

89 describes the series as a whole. 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

90 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

91 Each patch email has a Subject line of "[PATCH M of N] ...", using 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

92 the first line of the changeset description as the subject text. 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

93 The message contains two or three body parts. First, the rest of 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

94 the changeset description. Next, (optionally) if the diffstat 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

95 program is installed, the result of running diffstat on the patch. 
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset

96 Finally, the patch itself, as generated by "hg export".''' 
875  97 def prompt(prompt, default = None, rest = ': ', empty_ok = False): 
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

98 if default: prompt += ' [%s]' % default 
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

99 prompt += rest 
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

100 while True: 
875  101 r = raw_input(prompt) 
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

102 if r: return r 
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

103 if default is not None: return default 
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

104 if empty_ok: return r 
1670
fe19c54ee403
add _ to several strings
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1669
diff
changeset

105 ui.warn(_('Please enter a valid value.\n')) 
875  106 
107 def confirm(s):  
108 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'):  
109 raise ValueError  
110  
111 def cdiffstat(summary, patch):  
112 s = diffstat(patch)  
113 if s:  
114 if summary:  
115 ui.write(summary, '\n')  
116 ui.write(s, '\n')  
1670
fe19c54ee403
add _ to several strings
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1669
diff
changeset

117 confirm(_('Does the diffstat above look okay')) 
875  118 return s 
119  
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

120 def makepatch(patch, idx, total): 
875  121 desc = [] 
122 node = None  
1135
e455d91f6259
Variable 'body' was missing in patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1118
diff
changeset

123 body = '' 
875  124 for line in patch: 
125 if line.startswith('#'):  
126 if line.startswith('# Node ID'): node = line.split()[1]  
127 continue  
128 if line.startswith('diff r'): break  
129 desc.append(line)  
130 if not node: raise ValueError  
1118
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset

131 
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset

132 #body = ('\n'.join(desc[1:]).strip() or 
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset

133 # 'Patch subject is complete summary.') 
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset

134 #body += '\n\n\n' 
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset

135 
1604
da3f1121721b
add plain option to patchbomb.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1603
diff
changeset

136 if opts['plain']: 
da3f1121721b
add plain option to patchbomb.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1603
diff
changeset

137 while patch and patch[0].startswith('# '): patch.pop(0) 
da3f1121721b
add plain option to patchbomb.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1603
diff
changeset

138 if patch: patch.pop(0) 
da3f1121721b
add plain option to patchbomb.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1603
diff
changeset

139 while patch and not patch[0].strip(): patch.pop(0) 
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

140 if opts['diffstat']: 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

141 body += cdiffstat('\n'.join(desc), patch) + '\n\n' 
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

142 body += '\n'.join(patch) 
1827
26dd4ae77b7b
get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents:
1702
diff
changeset

143 msg = email.MIMEText.MIMEText(body) 
1846
4d2791f4ef80
only put numbers on patches if > 1 patch.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1845
diff
changeset

144 if total == 1: 
4d2791f4ef80
only put numbers on patches if > 1 patch.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1845
diff
changeset

145 subj = '[PATCH] ' + desc[0].strip() 
4d2791f4ef80
only put numbers on patches if > 1 patch.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1845
diff
changeset

146 else: 
4d2791f4ef80
only put numbers on patches if > 1 patch.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1845
diff
changeset

147 subj = '[PATCH %d of %d] %s' % (idx, total, desc[0].strip()) 
875  148 if subj.endswith('.'): subj = subj[:1] 
149 msg['Subject'] = subj  
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

150 msg['XMercurialNode'] = node 
875  151 return msg 
152  
153 start_time = int(time.time())  
154  
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

155 def genmsgid(id): 
875  156 return '<%s.%s@%s>' % (id[:20], start_time, socket.getfqdn()) 
157  
158 patches = []  
159  
160 class exportee:  
161 def __init__(self, container):  
162 self.lines = []  
163 self.container = container  
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

164 self.name = 'email' 
875  165 
166 def write(self, data):  
167 self.lines.append(data)  
168  
169 def close(self):  
170 self.container.append(''.join(self.lines).split('\n'))  
171 self.lines = []  
172  
1669
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

173 commands.export(ui, repo, *revs, **{'output': exportee(patches), 
1603
5352a5407dc1
make patchbomb work with recent changes to export
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1226
diff
changeset

174 'switch_parent': False, 
1032
706c590c9060
Get patchbomb working with tip again.
Bryan O'Sullivan <bos@serpentine.com>
parents:
998
diff
changeset

175 'text': None}) 
875  176 
177 jumbo = []  
178 msgs = []  
179  
1670
fe19c54ee403
add _ to several strings
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1669
diff
changeset

180 ui.write(_('This patch series consists of %d patches.\n\n') % len(patches)) 
875  181 
182 for p, i in zip(patches, range(len(patches))):  
183 jumbo.extend(p)  
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

184 msgs.append(makepatch(p, i + 1, len(patches))) 
875  185 
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

186 sender = (opts['from'] or ui.config('patchbomb', 'from') or 
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

187 prompt('From', ui.username())) 
875  188 
1154
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset

189 def getaddrs(opt, prpt, default = None): 
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset

190 addrs = opts[opt] or (ui.config('patchbomb', opt) or 
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset

191 prompt(prpt, default = default)).split(',') 
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset

192 return [a.strip() for a in addrs if a.strip()] 
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset

193 to = getaddrs('to', 'To') 
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset

194 cc = getaddrs('cc', 'Cc', '') 
875  195 
1845
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

196 if len(patches) > 1: 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

197 ui.write(_('\nWrite the introductory message for the patch series.\n\n')) 
875  198 
1845
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

199 msg = email.MIMEMultipart.MIMEMultipart() 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

200 msg['Subject'] = '[PATCH 0 of %d] %s' % ( 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

201 len(patches), 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

202 opts['subject'] or 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

203 prompt('Subject:', rest = ' [PATCH 0 of %d] ' % len(patches))) 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

204 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

205 ui.write(_('Finish with ^D or a dot on a line by itself.\n\n')) 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

206 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

207 body = [] 
875  208 
1845
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

209 while True: 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

210 try: l = raw_input() 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

211 except EOFError: break 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

212 if l == '.': break 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

213 body.append(l) 
875  214 
1845
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

215 msg.attach(email.MIMEText.MIMEText('\n'.join(body) + '\n')) 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

216 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

217 if opts['diffstat']: 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

218 d = cdiffstat(_('Final summary:\n'), jumbo) 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

219 if d: msg.attach(email.MIMEText.MIMEText(d)) 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

220 
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset

221 msgs.insert(0, msg) 
875  222 
223 ui.write('\n')  
224  
1702
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

225 if not opts['test'] and not opts['mbox']: 
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

226 s = smtplib.SMTP() 
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

227 s.connect(host = ui.config('smtp', 'host', 'mail'), 
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

228 port = int(ui.config('smtp', 'port', 25))) 
1226
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

229 if ui.configbool('smtp', 'tls'): 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

230 s.ehlo() 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

231 s.starttls() 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

232 s.ehlo() 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

233 username = ui.config('smtp', 'username') 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

234 password = ui.config('smtp', 'password') 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

235 if username and password: 
f3837564ed03
patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1204
diff
changeset

236 s.login(username, password) 
875  237 parent = None 
238 tz = time.strftime('%z')  
1827
26dd4ae77b7b
get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents:
1702
diff
changeset

239 sender_addr = email.Utils.parseaddr(sender)[1] 
875  240 for m in msgs: 
241 try:  
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

242 m['MessageId'] = genmsgid(m['XMercurialNode']) 
875  243 except TypeError: 
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

244 m['MessageId'] = genmsgid('patchbomb') 
875  245 if parent: 
246 m['InReplyTo'] = parent  
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

247 else: 
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

248 parent = m['MessageId'] 
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset

249 m['Date'] = time.strftime('%a, %e %b %Y %T ', time.localtime(start_time)) + tz 
875  250 start_time += 1 
251 m['From'] = sender  
252 m['To'] = ', '.join(to)  
253 if cc: m['Cc'] = ', '.join(cc)  
254 if opts['test']:  
1702
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

255 ui.status('Displaying ', m['Subject'], ' ...\n') 
875  256 fp = os.popen(os.getenv('PAGER', 'more'), 'w') 
1871
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset

257 try: 
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset

258 fp.write(m.as_string(0)) 
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset

259 fp.write('\n') 
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset

260 except IOError, inst: 
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset

261 if inst.errno != errno.EPIPE: 
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset

262 raise 
875  263 fp.close() 
1702
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

264 elif opts['mbox']: 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

265 ui.status('Writing ', m['Subject'], ' ...\n') 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

266 fp = open(opts['mbox'], m.has_key('InReplyTo') and 'ab+' or 'wb+') 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

267 date = time.asctime(time.localtime(start_time)) 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

268 fp.write('From %s %s\n' % (sender_addr, date)) 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

269 fp.write(m.as_string(0)) 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

270 fp.write('\n\n') 
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

271 fp.close() 
875  272 else: 
1702
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

273 ui.status('Sending ', m['Subject'], ' ...\n') 
875  274 s.sendmail(sender, to + cc, m.as_string(0)) 
1702
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

275 if not opts['test'] and not opts['mbox']: 
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset

276 s.close() 
875  277 
1669
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

278 cmdtable = { 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

279 'email': 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

280 (patchbomb, 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

281 [('c', 'cc', [], 'email addresses of copy recipients'), 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

282 ('d', 'diffstat', None, 'add diffstat output to messages'), 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

283 ('f', 'from', '', 'email address of sender'), 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

284 ('', 'plain', None, 'omit hg patch header'), 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

285 ('n', 'test', None, 'print messages that would be sent'), 
1702
e291d9a30bef
add mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset

286 ('m', 'mbox', '', 'write messages to mbox file instead of sending them'), 
1669
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

287 ('s', 'subject', '', 'subject of introductory message'), 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

288 ('t', 'to', [], 'email addresses of recipients')], 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

289 "hg email [OPTION]... [REV]...") 
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset

290 } 