annotate contrib/patchbomb @ 1375:f2b00be33e2c

Fix traceback when nothing was added during unbundle The changegroup and commit hook are now run only when something is modified. The correct number of changesets added is printed.
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Mon, 03 Oct 2005 14:45:14 -0700
parents f3837564ed03
children 5352a5407dc1
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
1226
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
38 # 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
39 # username = user # if SMTP authentication required
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
40 # password = password # if SMTP authentication required - PLAINTEXT
877
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 # 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
43 # file:
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
44 #
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
45 # [patchbomb]
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
46 # from = My Name <my@email>
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
47 # to = recipient1, recipient2, ...
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
48 # cc = cc1, cc2, ...
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
49
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 from email.MIMEMultipart import MIMEMultipart
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 from email.MIMEText import MIMEText
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 from mercurial import commands
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
53 from mercurial import fancyopts
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
54 from mercurial import hg
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
55 from mercurial import ui
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56 import os
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57 import popen2
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58 import smtplib
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
59 import socket
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
60 import sys
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
61 import tempfile
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62 import time
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
63
1204
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
64 try:
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
65 # 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
66 # present on windows
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
67 import readline
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
68 except ImportError: pass
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
69
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
70 def diffstat(patch):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
71 fd, name = tempfile.mkstemp()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 try:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
73 p = popen2.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
74 try:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75 for line in patch: print >> p.tochild, line
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
76 p.tochild.close()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
77 if p.wait(): return
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
78 fp = os.fdopen(fd, 'r')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
79 stat = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
80 for line in fp: stat.append(line.lstrip())
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
81 last = stat.pop()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
82 stat.insert(0, last)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
83 stat = ''.join(stat)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
84 if stat.startswith('0 files'): raise ValueError
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
85 return stat
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
86 except: raise
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87 finally:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
88 try: os.unlink(name)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
89 except: pass
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
90
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
91 def patchbomb(ui, repo, *revs, **opts):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
92 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
93 if default: prompt += ' [%s]' % default
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
94 prompt += rest
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
95 while True:
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
96 r = raw_input(prompt)
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
97 if r: return r
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
98 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
99 if empty_ok: return r
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
100 ui.warn('Please enter a valid value.\n')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
101
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
102 def confirm(s):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
103 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
104 raise ValueError
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
105
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
106 def cdiffstat(summary, patch):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
107 s = diffstat(patch)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
108 if s:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
109 if summary:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
110 ui.write(summary, '\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
111 ui.write(s, '\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
112 confirm('Does the diffstat above look okay')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
113 return s
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
114
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
115 def makepatch(patch, idx, total):
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
116 desc = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
117 node = None
1135
e455d91f6259 Variable 'body' was missing in patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1118
diff changeset
118 body = ''
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
119 for line in patch:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
120 if line.startswith('#'):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
121 if line.startswith('# Node ID'): node = line.split()[-1]
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
122 continue
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
123 if line.startswith('diff -r'): break
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
124 desc.append(line)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
125 if not node: raise ValueError
1118
63b5f68d8167 patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents: 1032
diff changeset
126
63b5f68d8167 patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents: 1032
diff changeset
127 #body = ('\n'.join(desc[1:]).strip() or
63b5f68d8167 patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents: 1032
diff changeset
128 # 'Patch subject is complete summary.')
63b5f68d8167 patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents: 1032
diff changeset
129 #body += '\n\n\n'
63b5f68d8167 patchbomb: eliminate silly complete summary message
mpm@selenic.com
parents: 1032
diff changeset
130
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
131 if opts['diffstat']:
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
132 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
133 body += '\n'.join(patch)
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
134 msg = MIMEText(body)
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
135 subj = '[PATCH %d of %d] %s' % (idx, total, desc[0].strip())
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
136 if subj.endswith('.'): subj = subj[:-1]
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
137 msg['Subject'] = subj
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
138 msg['X-Mercurial-Node'] = node
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
139 return msg
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
140
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
141 start_time = int(time.time())
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
142
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
143 def genmsgid(id):
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
144 return '<%s.%s@%s>' % (id[:20], start_time, socket.getfqdn())
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
145
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
146 patches = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
147
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
148 class exportee:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
149 def __init__(self, container):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
150 self.lines = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
151 self.container = container
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
152 self.name = 'email'
875
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 write(self, data):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
155 self.lines.append(data)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
156
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
157 def close(self):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
158 self.container.append(''.join(self.lines).split('\n'))
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
159 self.lines = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
160
1032
706c590c9060 Get patchbomb working with tip again.
Bryan O'Sullivan <bos@serpentine.com>
parents: 998
diff changeset
161 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
162 'text': None})
875
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 jumbo = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
165 msgs = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
166
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
167 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
168
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
169 for p, i in zip(patches, range(len(patches))):
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
170 jumbo.extend(p)
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
171 msgs.append(makepatch(p, i + 1, len(patches)))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
172
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
173 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
174
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
175 sender = (opts['from'] or ui.config('patchbomb', 'from') or
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
176 prompt('From', ui.username()))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
177
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
178 msg = MIMEMultipart()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
179 msg['Subject'] = '[PATCH 0 of %d] %s' % (
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
180 len(patches),
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
181 opts['subject'] or
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
182 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
183
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
184 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
185 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
186 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
187 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
188 to = getaddrs('to', 'To')
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
189 cc = getaddrs('cc', 'Cc', '')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
190
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
191 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
192
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
193 body = []
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
194
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
195 while True:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
196 try: l = raw_input()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
197 except EOFError: break
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
198 if l == '.': break
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
199 body.append(l)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
200
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
201 msg.attach(MIMEText('\n'.join(body) + '\n'))
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
202
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
203 ui.write('\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
204
1136
d451888505d7 Make diffstat optional for patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1135
diff changeset
205 if opts['diffstat']:
d451888505d7 Make diffstat optional for patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1135
diff changeset
206 d = cdiffstat('Final summary:\n', jumbo)
d451888505d7 Make diffstat optional for patchbomb script.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1135
diff changeset
207 if d: msg.attach(MIMEText(d))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
208
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
209 msgs.insert(0, msg)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
210
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
211 if not opts['test']:
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
212 s = smtplib.SMTP()
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
213 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
214 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
215 if ui.configbool('smtp', 'tls'):
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
216 s.ehlo()
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
217 s.starttls()
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
218 s.ehlo()
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
219 username = ui.config('smtp', 'username')
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
220 password = ui.config('smtp', 'password')
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
221 if username and password:
f3837564ed03 patchbomb: add TLS and SMTP AUTH support.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1204
diff changeset
222 s.login(username, password)
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
223 parent = None
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
224 tz = time.strftime('%z')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
225 for m in msgs:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
226 try:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
227 m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
228 except TypeError:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
229 m['Message-Id'] = genmsgid('patchbomb')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
230 if parent:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
231 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
232 else:
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
233 parent = m['Message-Id']
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
234 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
235 start_time += 1
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
236 m['From'] = sender
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
237 m['To'] = ', '.join(to)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
238 if cc: m['Cc'] = ', '.join(cc)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
239 ui.status('Sending ', m['Subject'], ' ...\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
240 if opts['test']:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
241 fp = os.popen(os.getenv('PAGER', 'more'), 'w')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
242 fp.write(m.as_string(0))
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
243 fp.write('\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
244 fp.close()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
245 else:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
246 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
247 if not opts['test']:
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
248 s.close()
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
249
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
250 if __name__ == '__main__':
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
251 optspec = [('c', 'cc', [], 'email addresses of copy recipients'),
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
252 ('d', 'diffstat', None, 'add diffstat output to messages'),
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
253 ('f', 'from', '', 'email address of sender'),
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
254 ('n', 'test', None, 'print messages that would be sent'),
877
25430c523677 Polish patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents: 876
diff changeset
255 ('s', 'subject', '', 'subject of introductory message'),
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
256 ('t', 'to', [], 'email addresses of recipients')]
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
257 options = {}
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
258 try:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
259 args = fancyopts.fancyopts(sys.argv[1:], commands.globalopts + optspec,
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
260 options)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
261 except fancyopts.getopt.GetoptError, inst:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
262 u = ui.ui()
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
263 u.warn('error: %s' % inst)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
264 sys.exit(1)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
265
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
266 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
267 not options["noninteractive"])
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
268 repo = hg.repository(ui = u)
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
269
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
270 patchbomb(u, repo, *args, **options)