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