annotate contrib/patchbomb @ 1225:ea90162e210c

Add --debugger global option With this option, hg will drop into the Python debugger on execution. Running 'continue' will execute normally, and the debugger will be reinvoked if an exception is raised.
author mpm@selenic.com
date Thu, 08 Sep 2005 17:09:31 -0700
parents b0f6053df539
children f3837564ed03
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1 #!/usr/bin/python
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
2 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
3 # Interactive script for sending a collection of Mercurial changesets
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
4 # as a series of patch emails.
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
5 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
6 # The series is started off with a "[PATCH 0 of N]" introduction,
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7 # which describes the series as a whole.
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
8 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
9 # Each patch email has a Subject line of "[PATCH M of N] ...", using
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
10 # the first line of the changeset description as the subject text.
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11 # The message contains two or three body parts:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
12 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
13 # The remainder of the changeset description.
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
14 #
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
15 # [Optional] If the diffstat program is installed, the result of
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
16 # running diffstat on the patch.
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
17 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
18 # The patch itself, as generated by "hg export".
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
20 # Each message refers to all of its predecessors using the In-Reply-To
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
21 # and References headers, so they will show up as a sequence in
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
22 # threaded mail and news readers, and in mail archives.
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
23 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
24 # For each changeset, you will be prompted with a diffstat summary and
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
25 # the changeset summary, so you can be sure you are sending the right
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
26 # changes.
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
27 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
28 # 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
29 # 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
30 # display each of the messages that it would send.
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
31 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
32 # To configure a default mail host, add a section like this to your
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
33 # hgrc file:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
34 #
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
35 # [smtp]
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
36 # host = my_mail_host
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
37 # port = 1025
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
38 #
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
39 # 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
40 # file:
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
41 #
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
42 # [patchbomb]
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
43 # from = My Name <my@email>
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
44 # to = recipient1, recipient2, ...
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
45 # cc = cc1, cc2, ...
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
47 from email.MIMEMultipart import MIMEMultipart
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
48 from email.MIMEText import MIMEText
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
49 from mercurial import commands
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 from mercurial import fancyopts
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 from mercurial import hg
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 from mercurial import ui
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
53 import os
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
54 import popen2
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
55 import smtplib
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56 import socket
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57 import sys
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58 import tempfile
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
59 import time
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
60
1204
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
61 try:
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
62 # 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
63 # present on windows
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
64 import readline
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
65 except ImportError: pass
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
66
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
67 def diffstat(patch):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
68 fd, name = tempfile.mkstemp()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
69 try:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
70 p = popen2.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
71 try:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 for line in patch: print >> p.tochild, line
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
73 p.tochild.close()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
74 if p.wait(): return
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75 fp = os.fdopen(fd, 'r')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
76 stat = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
77 for line in fp: stat.append(line.lstrip())
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
78 last = stat.pop()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
79 stat.insert(0, last)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
80 stat = ''.join(stat)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
81 if stat.startswith('0 files'): raise ValueError
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
82 return stat
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
83 except: raise
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
84 finally:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
85 try: os.unlink(name)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
86 except: pass
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
88 def patchbomb(ui, repo, *revs, **opts):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
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
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
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
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
97 ui.warn('Please enter a valid value.\n')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
98
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
99 def confirm(s):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
100 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
101 raise ValueError
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
102
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
103 def cdiffstat(summary, patch):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
104 s = diffstat(patch)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
105 if s:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
106 if summary:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
107 ui.write(summary, '\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
108 ui.write(s, '\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
109 confirm('Does the diffstat above look okay')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
110 return s
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
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
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
113 desc = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
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
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
116 for line in patch:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
117 if line.startswith('#'):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
118 if line.startswith('# Node ID'): node = line.split()[-1]
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
119 continue
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
120 if line.startswith('diff -r'): break
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
121 desc.append(line)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
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
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
128 if opts['diffstat']:
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
129 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
130 body += '\n'.join(patch)
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
131 msg = MIMEText(body)
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
132 subj = '[PATCH %d of %d] %s' % (idx, total, desc[0].strip())
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
133 if subj.endswith('.'): subj = subj[:-1]
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
134 msg['Subject'] = subj
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
135 msg['X-Mercurial-Node'] = node
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
136 return msg
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
137
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
138 start_time = int(time.time())
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
139
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
140 def genmsgid(id):
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
141 return '<%s.%s@%s>' % (id[:20], start_time, socket.getfqdn())
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
142
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
143 patches = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
144
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
145 class exportee:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
146 def __init__(self, container):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
147 self.lines = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
148 self.container = container
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
149 self.name = 'email'
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
150
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
151 def write(self, data):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
152 self.lines.append(data)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
153
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
154 def close(self):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
155 self.container.append(''.join(self.lines).split('\n'))
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
156 self.lines = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
157
1032
706c590c9060 Get patchbomb working with tip again.
Bryan O'Sullivan <bos@serpentine.com>
parents: 998
diff changeset
158 commands.export(ui, repo, *args, **{'output': exportee(patches),
706c590c9060 Get patchbomb working with tip again.
Bryan O'Sullivan <bos@serpentine.com>
parents: 998
diff changeset
159 'text': None})
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
160
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
161 jumbo = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
162 msgs = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
163
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
164 ui.write('This patch series consists of %d patches.\n\n' % len(patches))
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
165
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
166 for p, i in zip(patches, range(len(patches))):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
167 jumbo.extend(p)
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
168 msgs.append(makepatch(p, i + 1, len(patches)))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
169
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
170 ui.write('\nWrite the introductory message for the patch series.\n\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
171
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
172 sender = (opts['from'] or ui.config('patchbomb', 'from') or
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
173 prompt('From', ui.username()))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
174
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
175 msg = MIMEMultipart()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
176 msg['Subject'] = '[PATCH 0 of %d] %s' % (
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
177 len(patches),
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
178 opts['subject'] or
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
179 prompt('Subject:', rest = ' [PATCH 0 of %d] ' % len(patches)))
1154
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
180
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
181 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
182 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
183 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
184 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
185 to = getaddrs('to', 'To')
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
186 cc = getaddrs('cc', 'Cc', '')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
187
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
188 ui.write('Finish with ^D or a dot on a line by itself.\n\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
189
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
190 body = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
191
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
192 while True:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
193 try: l = raw_input()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
194 except EOFError: break
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
195 if l == '.': break
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
196 body.append(l)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
197
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
198 msg.attach(MIMEText('\n'.join(body) + '\n'))
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
199
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
200 ui.write('\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
201
1136
d451888505d7 Make diffstat optional for patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1135
diff changeset
202 if opts['diffstat']:
d451888505d7 Make diffstat optional for patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1135
diff changeset
203 d = cdiffstat('Final summary:\n', jumbo)
d451888505d7 Make diffstat optional for patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1135
diff changeset
204 if d: msg.attach(MIMEText(d))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
205
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
206 msgs.insert(0, msg)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
207
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
208 if not opts['test']:
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
209 s = smtplib.SMTP()
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
210 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
211 port = int(ui.config('smtp', 'port', 25)))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
212
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
213 parent = None
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
214 tz = time.strftime('%z')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
215 for m in msgs:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
216 try:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
217 m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
218 except TypeError:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
219 m['Message-Id'] = genmsgid('patchbomb')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
220 if parent:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
221 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
222 else:
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
223 parent = m['Message-Id']
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
224 m['Date'] = time.strftime('%a, %e %b %Y %T ', time.localtime(start_time)) + tz
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
225 start_time += 1
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
226 m['From'] = sender
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
227 m['To'] = ', '.join(to)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
228 if cc: m['Cc'] = ', '.join(cc)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
229 ui.status('Sending ', m['Subject'], ' ...\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
230 if opts['test']:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
231 fp = os.popen(os.getenv('PAGER', 'more'), 'w')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
232 fp.write(m.as_string(0))
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
233 fp.write('\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
234 fp.close()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
235 else:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
236 s.sendmail(sender, to + cc, m.as_string(0))
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
237 if not opts['test']:
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
238 s.close()
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
239
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
240 if __name__ == '__main__':
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
241 optspec = [('c', 'cc', [], 'email addresses of copy recipients'),
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
242 ('d', 'diffstat', None, 'add diffstat output to messages'),
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
243 ('f', 'from', '', 'email address of sender'),
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
244 ('n', 'test', None, 'print messages that would be sent'),
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
245 ('s', 'subject', '', 'subject of introductory message'),
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
246 ('t', 'to', [], 'email addresses of recipients')]
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
247 options = {}
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
248 try:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
249 args = fancyopts.fancyopts(sys.argv[1:], commands.globalopts + optspec,
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
250 options)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
251 except fancyopts.getopt.GetoptError, inst:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
252 u = ui.ui()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
253 u.warn('error: %s' % inst)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
254 sys.exit(1)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
255
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
256 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
257 not options["noninteractive"])
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
258 repo = hg.repository(ui = u)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
259
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
260 patchbomb(u, repo, *args, **options)