40
38
_smtplib_implementation = SMTPConnection
42
40
def __init__(self, branch, revision_id, config, local_branch=None,
44
42
self.config = config
45
43
self.branch = branch
46
44
self.repository = branch.repository
47
45
if (local_branch is not None and
48
local_branch.repository.has_revision(revision_id)):
46
local_branch.repository.has_revision(revision_id)):
49
47
self.repository = local_branch.repository
50
48
self._revision_id = revision_id
51
49
self.revision = None
126
124
revid_new = self.revision.revision_id
127
125
if self.revision.parent_ids:
128
126
revid_old = self.revision.parent_ids[0]
129
tree_new, tree_old = self.repository.revision_trees((revid_new, revid_old))
127
tree_new, tree_old = self.repository.revision_trees(
128
(revid_new, revid_old))
131
130
# revision_trees() doesn't allow None or 'null:' to be passed as a
132
131
# revision. So we need to call revision_tree() twice.
137
136
# We can use a StringIO because show_diff_trees should only write
138
137
# 8-bit strings. It is an error to write a Unicode string here.
139
from ...sixish import StringIO
138
from io import StringIO
140
139
diff_content = StringIO()
141
140
diff_options = self.config.get('post_commit_diffoptions')
142
141
show_diff_trees(tree_old, tree_new, diff_content, None, diff_options)
143
numlines = diff_content.getvalue().count('\n')+1
142
numlines = diff_content.getvalue().count('\n') + 1
144
143
if numlines <= difflimit:
145
144
return diff_content.getvalue()
212
211
"""Spawn a 'mail' subprocess to send the email."""
213
212
# TODO think up a good test for this, but I think it needs
214
213
# a custom binary shipped with. RBC 20051021
215
msgfile = tempfile.NamedTemporaryFile()
214
with tempfile.NamedTemporaryFile() as msgfile:
217
215
msgfile.write(self.body().encode('utf8'))
218
216
diff = self.get_diff()
224
222
process = subprocess.Popen(self._command_line(),
225
stdin=msgfile.fileno())
223
stdin=msgfile.fileno())
227
225
rc = process.wait()
229
raise errors.BzrError("Failed to send email: exit status %s" % (rc,))
227
raise errors.BzrError(
228
"Failed to send email: exit status %s" % (rc,))
233
230
def _send_using_smtplib(self):
234
231
"""Use python's smtplib to send the email."""
269
266
def subject(self):
270
267
_subject = self.config.get('post_commit_subject')
271
268
if _subject is None:
272
_subject = ("Rev %d: %s in %s" %
274
self.revision.get_summary(),
269
_subject = ("Rev %d: %s in %s" %
271
self.revision.get_summary(),
276
273
return self._format(_subject)
278
275
def diff_filename(self):
282
279
opt_post_commit_body = Option("post_commit_body",
283
help="Body for post commit emails.")
280
help="Body for post commit emails.")
284
281
opt_post_commit_subject = Option("post_commit_subject",
285
help="Subject for post commit emails.")
282
help="Subject for post commit emails.")
286
283
opt_post_commit_log_format = Option('post_commit_log_format',
287
default='long', help="Log format for option.")
284
default='long', help="Log format for option.")
288
285
opt_post_commit_difflimit = Option('post_commit_difflimit',
289
default=1000, from_unicode=int_from_store,
290
help="Maximum number of lines in diffs.")
286
default=1000, from_unicode=int_from_store,
287
help="Maximum number of lines in diffs.")
291
288
opt_post_commit_push_pull = Option('post_commit_push_pull',
292
from_unicode=bool_from_store,
293
help="Whether to send emails on push and pull.")
289
from_unicode=bool_from_store,
290
help="Whether to send emails on push and pull.")
294
291
opt_post_commit_diffoptions = Option('post_commit_diffoptions',
295
help="Diff options to use.")
292
help="Diff options to use.")
296
293
opt_post_commit_sender = Option('post_commit_sender',
297
help='From address to use for emails.')
294
help='From address to use for emails.')
298
295
opt_post_commit_to = ListOption('post_commit_to',
299
help='Address to send commit emails to.')
296
help='Address to send commit emails to.')
300
297
opt_post_commit_mailer = Option('post_commit_mailer',
301
help='Mail client to use.', default='mail')
298
help='Mail client to use.', default='mail')
302
299
opt_post_commit_url = Option('post_commit_url',
303
help='URL to mention for branch in post commit messages.')
300
help='URL to mention for branch in post commit messages.')
304
301
opt_revision_mail_headers = ListOption('revision_mail_headers',
305
help="Extra revision headers.")
302
help="Extra revision headers.")