Rev 24: Switch to using a local repository if available, in http://bazaar.launchpad.net/%7Ebzr/bzr-email/trunk
John Arbash Meinel
john at arbash-meinel.com
Sat Feb 17 18:09:27 GMT 2007
At http://bazaar.launchpad.net/%7Ebzr/bzr-email/trunk
------------------------------------------------------------
revno: 24
revision-id: john at arbash-meinel.com-20070217180912-adzv4po94phzm6h4
parent: john at arbash-meinel.com-20070207223737-deytpas3j166sz72
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: email
timestamp: Sat 2007-02-17 12:09:12 -0600
message:
Switch to using a local repository if available,
also do most actions inside a single read lock, so the repository
information doesn't need to be read repeatedly.
modified:
__init__.py __init__.py-20051018071212-f1765ec4521cab0b
emailer.py emailer.py-20070123220937-ec5y2n2oeoa0p4ue-1
tests/testemail.py testpublish.py-20051018071212-e3a53d78c05e0e0a
-------------- next part --------------
=== modified file '__init__.py'
--- a/__init__.py 2007-02-07 22:37:37 +0000
+++ b/__init__.py 2007-02-17 18:09:12 +0000
@@ -48,7 +48,8 @@
def branch_commit_hook(local, master, old_revno, old_revid, new_revno, new_revid):
"""This is the post_commit hook that runs after commit."""
- _emailer.EmailSender(master, new_revid, master.get_config()).send_maybe()
+ _emailer.EmailSender(master, new_revid, master.get_config(),
+ local_branch=local).send_maybe()
def install_hooks():
=== modified file 'emailer.py'
--- a/emailer.py 2007-01-27 14:53:08 +0000
+++ b/emailer.py 2007-02-17 18:09:12 +0000
@@ -30,11 +30,20 @@
_smtplib_implementation = SMTPConnection
- def __init__(self, branch, revision_id, config):
+ def __init__(self, branch, revision_id, config, local_branch=None):
self.config = config
self.branch = branch
- self.revision = self.branch.repository.get_revision(revision_id)
- self.revno = self.branch.revision_id_to_revno(revision_id)
+ self.repository = branch.repository
+ if (local_branch is not None and
+ local_branch.repository.has_revision(revision_id)):
+ self.repository = local_branch.repository
+ self._revision_id = revision_id
+ self.revision = None
+ self.revno = None
+
+ def _setup_revision_and_revno(self):
+ self.revision = self.repository.get_revision(self._revision_id)
+ self.revno = self.branch.revision_id_to_revno(self._revision_id)
def body(self):
from bzrlib.log import log_formatter, show_log
@@ -83,13 +92,13 @@
revid_new = self.revision.revision_id
if self.revision.parent_ids:
revid_old = self.revision.parent_ids[0]
- tree_new, tree_old = self.branch.repository.revision_trees((revid_new, revid_old))
+ tree_new, tree_old = self.repository.revision_trees((revid_new, revid_old))
else:
# revision_trees() doesn't allow None or 'null:' to be passed as a
# revision. So we need to call revision_tree() twice.
revid_old = _mod_revision.NULL_REVISION
- tree_new = self.branch.repository.revision_tree(revid_new)
- tree_old = self.branch.repository.revision_tree(revid_old)
+ tree_new = self.repository.revision_tree(revid_new)
+ tree_old = self.repository.revision_tree(revid_old)
# We can use a cStringIO because show_diff_trees should only write
# 8-bit strings. It is an error to write a Unicode string here.
@@ -154,11 +163,19 @@
Depending on the configuration, this will either use smtplib, or it
will call out to the 'mail' program.
"""
- mailer = self.mailer()
- if mailer == 'smtplib':
- self._send_using_smtplib()
- else:
- self._send_using_process()
+ self.branch.lock_read()
+ self.repository.lock_read()
+ try:
+ # Do this after we have locked, to make things faster.
+ self._setup_revision_and_revno()
+ mailer = self.mailer()
+ if mailer == 'smtplib':
+ self._send_using_smtplib()
+ else:
+ self._send_using_process()
+ finally:
+ self.repository.unlock()
+ self.branch.unlock()
def _send_using_process(self):
"""Spawn a 'mail' subprocess to send the email."""
=== modified file 'tests/testemail.py'
--- a/tests/testemail.py 2007-01-27 14:53:08 +0000
+++ b/tests/testemail.py 2007-02-17 18:09:12 +0000
@@ -20,6 +20,7 @@
from bzrlib import (
config,
+ tests,
)
from bzrlib.bzrdir import BzrDir
from bzrlib.tests import TestCaseInTempDir
@@ -53,6 +54,7 @@
"post_commit_to=demo at example.com\n"
"post_commit_sender=Sample <foo at example.com>\n")
+
class TestGetTo(TestCaseInTempDir):
def test_body(self):
@@ -156,6 +158,55 @@
my_config = self.branch.get_config()
config_file = StringIO(text)
(my_config._get_global_config()._get_parser(config_file))
- return EmailSender(self.branch, 'A', my_config)
-
-
+ sender = EmailSender(self.branch, 'A', my_config)
+ # This is usually only done after the EmailSender has locked the branch
+ # and repository during send(), however, for testing, we need to do it
+ # earlier, since send() is not called.
+ sender._setup_revision_and_revno()
+ return sender
+
+
+class TestEmailerWithLocal(tests.TestCaseWithTransport):
+ """Test that Emailer will use a local branch if supplied."""
+
+ def test_local_has_revision(self):
+ master_tree = self.make_branch_and_tree('master')
+ self.build_tree(['master/a'])
+ master_tree.add('a')
+ master_tree.commit('a')
+
+ child_tree = master_tree.bzrdir.sprout('child').open_workingtree()
+ child_tree.branch.bind(master_tree.branch)
+
+ self.build_tree(['child/b'])
+ child_tree.add(['b'])
+ revision_id = child_tree.commit('b')
+
+ sender = EmailSender(master_tree.branch, revision_id,
+ master_tree.branch.get_config(),
+ local_branch=child_tree.branch)
+
+ # Make sure we are using the 'local_branch' repository, and not the
+ # remote one.
+ self.assertIs(child_tree.branch.repository, sender.repository)
+
+ def test_local_missing_revision(self):
+ master_tree = self.make_branch_and_tree('master')
+ self.build_tree(['master/a'])
+ master_tree.add('a')
+ master_tree.commit('a')
+
+ child_tree = master_tree.bzrdir.sprout('child').open_workingtree()
+ child_tree.branch.bind(master_tree.branch)
+
+ self.build_tree(['master/c'])
+ master_tree.add(['c'])
+ revision_id = master_tree.commit('c')
+
+ self.failIf(child_tree.branch.repository.has_revision(revision_id))
+ sender = EmailSender(master_tree.branch, revision_id,
+ master_tree.branch.get_config(),
+ local_branch=child_tree.branch)
+ # We should be using the master repository here, because the child
+ # repository doesn't contain the revision.
+ self.assertIs(master_tree.branch.repository, sender.repository)
More information about the bazaar-commits
mailing list