Mercurial > public > mercurial-scm > hg
annotate hgext/patchbomb.py @ 2708:084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
if rev being emailed has tag that ends in .patch or .diff then use that as
filename. else make up filename from name of repo.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Thu, 27 Jul 2006 15:19:58 -0700 |
parents | 4af7b178976a |
children | 10e95059ffd7 |
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 In-Reply-To | |
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 # |
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset
|
34 # 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
|
35 # file: |
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset
|
36 # |
2198
564034552f7f
rename [patchbomb] section to [email] section in hgrc. old name still ok.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2165
diff
changeset
|
37 # [email] |
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset
|
38 # from = My Name <my@email> |
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset
|
39 # to = recipient1, recipient2, ... |
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset
|
40 # cc = cc1, cc2, ... |
2679
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
41 # bcc = bcc1, bcc2, ... |
875 | 42 |
1827
26dd4ae77b7b
get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents:
1702
diff
changeset
|
43 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
|
44 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
|
45 mercurial:commands,hg,ui |
2200
9f43b6e24232
move mail sending code into core, so extensions can share it.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2198
diff
changeset
|
46 os errno popen2 socket sys tempfile time''') |
1671
ba30c17d55f6
forgot to add import statement for _.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset
|
47 from mercurial.i18n import gettext as _ |
2708
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
48 from mercurial.node import * |
875 | 49 |
1204
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset
|
50 try: |
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset
|
51 # 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
|
52 # present on windows |
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset
|
53 import readline |
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset
|
54 except ImportError: pass |
b0f6053df539
patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1154
diff
changeset
|
55 |
875 | 56 def diffstat(patch): |
2165
d821918e3bee
Use better names (hg-{usage}-{random}.{suffix}) for temporary files.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1871
diff
changeset
|
57 fd, name = tempfile.mkstemp(prefix="hg-patchbomb-", suffix=".txt") |
875 | 58 try: |
59 p = popen2.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name) | |
60 try: | |
61 for line in patch: print >> p.tochild, line | |
62 p.tochild.close() | |
63 if p.wait(): return | |
64 fp = os.fdopen(fd, 'r') | |
65 stat = [] | |
66 for line in fp: stat.append(line.lstrip()) | |
67 last = stat.pop() | |
68 stat.insert(0, last) | |
69 stat = ''.join(stat) | |
70 if stat.startswith('0 files'): raise ValueError | |
71 return stat | |
72 except: raise | |
73 finally: | |
74 try: os.unlink(name) | |
75 except: pass | |
76 | |
77 def patchbomb(ui, repo, *revs, **opts): | |
1672
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset
|
78 '''send changesets as a series of patch emails |
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset
|
79 |
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset
|
80 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
|
81 describes the series as a whole. |
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset
|
82 |
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset
|
83 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
|
84 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
|
85 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
|
86 the changeset description. Next, (optionally) if the diffstat |
07f931af5f40
add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1670
diff
changeset
|
87 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
|
88 Finally, the patch itself, as generated by "hg export".''' |
875 | 89 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
|
90 if default: prompt += ' [%s]' % default |
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
91 prompt += rest |
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
92 while True: |
875 | 93 r = raw_input(prompt) |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
94 if r: return r |
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
95 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
|
96 if empty_ok: return r |
1670
fe19c54ee403
add _ to several strings
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1669
diff
changeset
|
97 ui.warn(_('Please enter a valid value.\n')) |
875 | 98 |
99 def confirm(s): | |
100 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'): | |
101 raise ValueError | |
102 | |
103 def cdiffstat(summary, patch): | |
104 s = diffstat(patch) | |
105 if s: | |
106 if summary: | |
107 ui.write(summary, '\n') | |
108 ui.write(s, '\n') | |
1670
fe19c54ee403
add _ to several strings
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1669
diff
changeset
|
109 confirm(_('Does the diffstat above look okay')) |
875 | 110 return s |
111 | |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
112 def makepatch(patch, idx, total): |
875 | 113 desc = [] |
114 node = None | |
1135
e455d91f6259
Variable 'body' was missing in patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1118
diff
changeset
|
115 body = '' |
875 | 116 for line in patch: |
117 if line.startswith('#'): | |
118 if line.startswith('# Node ID'): node = line.split()[-1] | |
119 continue | |
120 if line.startswith('diff -r'): break | |
121 desc.append(line) | |
122 if not node: raise ValueError | |
1118
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset
|
123 |
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset
|
124 #body = ('\n'.join(desc[1:]).strip() or |
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset
|
125 # 'Patch subject is complete summary.') |
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset
|
126 #body += '\n\n\n' |
63b5f68d8167
patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents:
1032
diff
changeset
|
127 |
1604
da3f1121721b
add --plain option to patchbomb.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1603
diff
changeset
|
128 if opts['plain']: |
da3f1121721b
add --plain option to patchbomb.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1603
diff
changeset
|
129 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
|
130 if patch: patch.pop(0) |
da3f1121721b
add --plain option to patchbomb.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1603
diff
changeset
|
131 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
|
132 if opts['diffstat']: |
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset
|
133 body += cdiffstat('\n'.join(desc), patch) + '\n\n' |
2707
4af7b178976a
patchbomb: optionally send patches as inline attachments
Christian Ebert <blacktrash@gmx.net>
parents:
2705
diff
changeset
|
134 if opts['attach']: |
4af7b178976a
patchbomb: optionally send patches as inline attachments
Christian Ebert <blacktrash@gmx.net>
parents:
2705
diff
changeset
|
135 msg = email.MIMEMultipart.MIMEMultipart() |
4af7b178976a
patchbomb: optionally send patches as inline attachments
Christian Ebert <blacktrash@gmx.net>
parents:
2705
diff
changeset
|
136 if body: msg.attach(email.MIMEText.MIMEText(body, 'plain')) |
2708
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
137 p = email.MIMEText.MIMEText('\n'.join(patch), 'x-patch') |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
138 node = bin(node) |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
139 # if node is mq patch, it will have patch file name as tag |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
140 patchname = [t for t in repo.nodetags(node) |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
141 if t.endswith('.patch') or t.endswith('.diff')] |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
142 if patchname: |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
143 patchname = patchname[0] |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
144 elif total > 1: |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
145 patchname = commands.make_filename(repo, '%b-%n.patch', |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
146 node, idx, total) |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
147 else: |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
148 patchname = commands.make_filename(repo, '%b.patch', node) |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
149 p['Content-Disposition'] = 'inline; filename=' + patchname |
084f07cacba0
patchbomb: add content-disposition to make display inline and add filename
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2707
diff
changeset
|
150 msg.attach(p) |
2707
4af7b178976a
patchbomb: optionally send patches as inline attachments
Christian Ebert <blacktrash@gmx.net>
parents:
2705
diff
changeset
|
151 else: |
4af7b178976a
patchbomb: optionally send patches as inline attachments
Christian Ebert <blacktrash@gmx.net>
parents:
2705
diff
changeset
|
152 body += '\n'.join(patch) |
4af7b178976a
patchbomb: optionally send patches as inline attachments
Christian Ebert <blacktrash@gmx.net>
parents:
2705
diff
changeset
|
153 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
|
154 if total == 1: |
4d2791f4ef80
only put numbers on patches if > 1 patch.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1845
diff
changeset
|
155 subj = '[PATCH] ' + desc[0].strip() |
4d2791f4ef80
only put numbers on patches if > 1 patch.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1845
diff
changeset
|
156 else: |
4d2791f4ef80
only put numbers on patches if > 1 patch.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1845
diff
changeset
|
157 subj = '[PATCH %d of %d] %s' % (idx, total, desc[0].strip()) |
875 | 158 if subj.endswith('.'): subj = subj[:-1] |
159 msg['Subject'] = subj | |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
160 msg['X-Mercurial-Node'] = node |
875 | 161 return msg |
162 | |
163 start_time = int(time.time()) | |
164 | |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
165 def genmsgid(id): |
875 | 166 return '<%s.%s@%s>' % (id[:20], start_time, socket.getfqdn()) |
167 | |
168 patches = [] | |
169 | |
170 class exportee: | |
171 def __init__(self, container): | |
172 self.lines = [] | |
173 self.container = container | |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
174 self.name = 'email' |
875 | 175 |
176 def write(self, data): | |
177 self.lines.append(data) | |
178 | |
179 def close(self): | |
180 self.container.append(''.join(self.lines).split('\n')) | |
181 self.lines = [] | |
182 | |
1669
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
183 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
|
184 'switch_parent': False, |
1032
706c590c9060
Get patchbomb working with tip again.
Bryan O'Sullivan <bos@serpentine.com>
parents:
998
diff
changeset
|
185 'text': None}) |
875 | 186 |
187 jumbo = [] | |
188 msgs = [] | |
189 | |
1670
fe19c54ee403
add _ to several strings
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1669
diff
changeset
|
190 ui.write(_('This patch series consists of %d patches.\n\n') % len(patches)) |
875 | 191 |
192 for p, i in zip(patches, range(len(patches))): | |
193 jumbo.extend(p) | |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
194 msgs.append(makepatch(p, i + 1, len(patches))) |
875 | 195 |
2198
564034552f7f
rename [patchbomb] section to [email] section in hgrc. old name still ok.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2165
diff
changeset
|
196 sender = (opts['from'] or ui.config('email', 'from') or |
564034552f7f
rename [patchbomb] section to [email] section in hgrc. old name still ok.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2165
diff
changeset
|
197 ui.config('patchbomb', 'from') or |
877
25430c523677
Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
876
diff
changeset
|
198 prompt('From', ui.username())) |
875 | 199 |
1154
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset
|
200 def getaddrs(opt, prpt, default = None): |
2198
564034552f7f
rename [patchbomb] section to [email] section in hgrc. old name still ok.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2165
diff
changeset
|
201 addrs = opts[opt] or (ui.config('email', opt) or |
564034552f7f
rename [patchbomb] section to [email] section in hgrc. old name still ok.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2165
diff
changeset
|
202 ui.config('patchbomb', opt) or |
1154
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset
|
203 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
|
204 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
|
205 to = getaddrs('to', 'To') |
c3cb9f39a91f
patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents:
1136
diff
changeset
|
206 cc = getaddrs('cc', 'Cc', '') |
875 | 207 |
2679
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
208 bcc = opts['bcc'] or (ui.config('email', 'bcc') or |
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
209 ui.config('patchbomb', 'bcc') or '').split(',') |
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
210 bcc = [a.strip() for a in bcc if a.strip()] |
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
211 |
1845
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 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
|
213 ui.write(_('\nWrite the introductory message for the patch series.\n\n')) |
875 | 214 |
2704
99e7cf6bd2f7
make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
215 subj = '[PATCH 0 of %d] %s' % ( |
1845
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset
|
216 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
|
217 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
|
218 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
|
219 |
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset
|
220 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
|
221 |
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset
|
222 body = [] |
875 | 223 |
1845
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset
|
224 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
|
225 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
|
226 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
|
227 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
|
228 body.append(l) |
875 | 229 |
1845
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset
|
230 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
|
231 d = cdiffstat(_('Final summary:\n'), jumbo) |
2704
99e7cf6bd2f7
make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
232 if d: body.append('\n' + d) |
99e7cf6bd2f7
make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
233 |
99e7cf6bd2f7
make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
234 body = '\n'.join(body) + '\n' |
99e7cf6bd2f7
make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
235 |
99e7cf6bd2f7
make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
236 msg = email.MIMEText.MIMEText(body) |
99e7cf6bd2f7
make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
237 msg['Subject'] = subj |
1845
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset
|
238 |
cfe689ab3f06
Patchbomb only sends introductory message [0 of N] if there are multiple patches.
Lee Cantey <lcantey@gmail.com>
parents:
1827
diff
changeset
|
239 msgs.insert(0, msg) |
875 | 240 |
241 ui.write('\n') | |
242 | |
1702
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
243 if not opts['test'] and not opts['mbox']: |
2200
9f43b6e24232
move mail sending code into core, so extensions can share it.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2198
diff
changeset
|
244 mail = ui.sendmail() |
875 | 245 parent = None |
2443
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
246 |
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
247 # Calculate UTC offset |
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
248 if time.daylight: offset = time.altzone |
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
249 else: offset = time.timezone |
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
250 if offset <= 0: sign, offset = '+', -offset |
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
251 else: sign = '-' |
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
252 offset = '%s%02d%02d' % (sign, offset / 3600, (offset % 3600) / 60) |
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
253 |
1827
26dd4ae77b7b
get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents:
1702
diff
changeset
|
254 sender_addr = email.Utils.parseaddr(sender)[1] |
875 | 255 for m in msgs: |
256 try: | |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
257 m['Message-Id'] = genmsgid(m['X-Mercurial-Node']) |
875 | 258 except TypeError: |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
259 m['Message-Id'] = genmsgid('patchbomb') |
875 | 260 if parent: |
261 m['In-Reply-To'] = parent | |
876
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
262 else: |
14cfaaec2e8e
Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents:
875
diff
changeset
|
263 parent = m['Message-Id'] |
2443
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
264 m['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(start_time)) + ' ' + offset |
bd9c39e8f38b
patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
2292
diff
changeset
|
265 |
875 | 266 start_time += 1 |
267 m['From'] = sender | |
268 m['To'] = ', '.join(to) | |
2679
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
269 if cc: m['Cc'] = ', '.join(cc) |
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
270 if bcc: m['Bcc'] = ', '.join(bcc) |
875 | 271 if opts['test']: |
1702
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
272 ui.status('Displaying ', m['Subject'], ' ...\n') |
875 | 273 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
|
274 try: |
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset
|
275 fp.write(m.as_string(0)) |
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset
|
276 fp.write('\n') |
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset
|
277 except IOError, inst: |
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset
|
278 if inst.errno != errno.EPIPE: |
258e3a7955b8
patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1846
diff
changeset
|
279 raise |
875 | 280 fp.close() |
1702
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
281 elif opts['mbox']: |
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
282 ui.status('Writing ', m['Subject'], ' ...\n') |
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
283 fp = open(opts['mbox'], m.has_key('In-Reply-To') and 'ab+' or 'wb+') |
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
284 date = time.asctime(time.localtime(start_time)) |
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
285 fp.write('From %s %s\n' % (sender_addr, date)) |
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
286 fp.write(m.as_string(0)) |
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
287 fp.write('\n\n') |
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
288 fp.close() |
875 | 289 else: |
1702
e291d9a30bef
add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents:
1691
diff
changeset
|
290 ui.status('Sending ', m['Subject'], ' ...\n') |
2679
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
291 mail.sendmail(sender, to + bcc + cc, m.as_string(0)) |
875 | 292 |
1669
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
293 cmdtable = { |
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
294 'email': |
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
295 (patchbomb, |
2707
4af7b178976a
patchbomb: optionally send patches as inline attachments
Christian Ebert <blacktrash@gmx.net>
parents:
2705
diff
changeset
|
296 [('a', 'attach', None, 'send patches as inline attachments'), |
4af7b178976a
patchbomb: optionally send patches as inline attachments
Christian Ebert <blacktrash@gmx.net>
parents:
2705
diff
changeset
|
297 ('', 'bcc', [], 'email addresses of blind copy recipients'), |
2679
f1de91be1d87
optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents:
2443
diff
changeset
|
298 ('c', 'cc', [], 'email addresses of copy recipients'), |
1669
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
299 ('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
|
300 ('f', 'from', '', 'email address of sender'), |
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
301 ('', 'plain', None, 'omit hg patch header'), |
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
302 ('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
|
303 ('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
|
304 ('s', 'subject', '', 'subject of introductory message'), |
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
305 ('t', 'to', [], 'email addresses of recipients')], |
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
306 "hg email [OPTION]... [REV]...") |
91d40fc959f0
turn patchbomb script into an extension module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1604
diff
changeset
|
307 } |