Rev 3365: Use mail-user-agent for Emacs mail clients (xma) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Sun Apr 13 20:44:36 BST 2008
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3365
revision-id:pqm at pqm.ubuntu.com-20080413194429-a5e4pft9sffa2ycu
parent: pqm at pqm.ubuntu.com-20080412084839-344825k3wbmbzzzf
parent: aaron at aaronbentley.com-20080413174114-kktjwgp1ahjimcn9
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Sun 2008-04-13 20:44:29 +0100
message:
Use mail-user-agent for Emacs mail clients (xma)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/config.py config.py-20051011043216-070c74f4e9e338e8
bzrlib/mail_client.py mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
------------------------------------------------------------
revno: 3364.1.2
revision-id:aaron at aaronbentley.com-20080413174114-kktjwgp1ahjimcn9
parent: aaron at aaronbentley.com-20080413173834-tzh23thfzx23121c
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: bzr.ab.integration
timestamp: Sun 2008-04-13 13:41:14 -0400
message:
Update NEWS for 1.5 cycle
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
------------------------------------------------------------
revno: 3364.1.1
revision-id:aaron at aaronbentley.com-20080413173834-tzh23thfzx23121c
parent: pqm at pqm.ubuntu.com-20080412084839-344825k3wbmbzzzf
parent: xma at gnu.org-20080413114800-b3tp394elic1793b
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: bzr.ab.integration
timestamp: Sun 2008-04-13 13:38:34 -0400
message:
Merge Emacs mail-user-agent patch
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/config.py config.py-20051011043216-070c74f4e9e338e8
bzrlib/mail_client.py mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
------------------------------------------------------------
revno: 3324.4.1
revision-id:xma at gnu.org-20080413114800-b3tp394elic1793b
parent: pqm at pqm.ubuntu.com-20080401091848-6y4f104r061ad8bk
committer: Xavier Maillard <xma at gnu.org>
branch nick: xma-emacsclient
timestamp: Sun 2008-04-13 13:48:00 +0200
message:
Replace mail-mode call with compose-mail from GNU Emacs.
This patch is a modified version of the current revno 3323.
It overloads it by:
1. defining a different python class EmacsMail "MUA agnostic".
To use this option, just put these lines into ~/.bazaar/bazaar.conf
[DEFAULT]
mail_client = emacsclient
2. supporting any mail client of GNU Emacs family (mail-mode,
message-mode, ...) The right tool will be called according to the
value of the variable ``mail-user-agent``. So Virtually any Emacs
mail client will work transparently if registered against
``mail-user-agent``.
3. adding a wrapper function around MIME attachment. This allow us not
to have many different functions/classes to attach a file but one.
4. tests have been updated to follow the changes.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/config.py config.py-20051011043216-070c74f4e9e338e8
bzrlib/mail_client.py mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
=== modified file 'NEWS'
--- a/NEWS 2008-04-12 06:46:35 +0000
+++ b/NEWS 2008-04-13 17:41:14 +0000
@@ -12,6 +12,29 @@
CHANGES:
+ * Broader support of GNU Emacs mail clients. Set
+ ``mail_client=emacsclient`` in your bazaar.conf and ``send`` will pop the
+ bundle in a mail buffer according to the value of ``mail-user-agent``
+ variable. (Xavier Maillard)
+
+ FEATURES:
+
+ IMPROVEMENTS:
+
+ BUGFIXES:
+
+ DOCUMENTATION:
+
+ TESTING:
+
+ INTERNALS:
+
+ API BREAKS:
+
+
+bzr 1.4rc1 2008-04-11
+---------------------
+
* bzr main script cannot be imported (Benjamin Peterson)
* On Linux bzr additionally looks for plugins in arch-independent site
@@ -36,9 +59,6 @@
FEATURES:
- * Added mail-mode GNU Emacs mail package as a mail_client.
- (Xavier Maillard, Bojan Nikolic)
-
* Added start_commit hook for mutable trees. (Jelmer Vernooij, #186422)
* ``status`` now accepts ``--no-pending`` to show the status without
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py 2008-04-10 13:30:05 +0000
+++ b/bzrlib/config.py 2008-04-13 17:38:34 +0000
@@ -151,6 +151,7 @@
mail_client_class = {
None: mail_client.DefaultMail,
# Specific clients
+ 'emacsclient': mail_client.EmacsMail,
'evolution': mail_client.Evolution,
'kmail': mail_client.KMail,
'mutt': mail_client.Mutt,
@@ -159,7 +160,6 @@
'default': mail_client.DefaultMail,
'editor': mail_client.Editor,
'mapi': mail_client.MAPIClient,
- 'emacs-mailmode': mail_client.EmacsMailMode,
'xdg-email': mail_client.XDGEmail,
}[selected_client]
except KeyError:
=== modified file 'bzrlib/mail_client.py'
--- a/bzrlib/mail_client.py 2008-04-01 04:19:06 +0000
+++ b/bzrlib/mail_client.py 2008-04-13 11:48:00 +0000
@@ -306,16 +306,67 @@
return commandline
-class EmacsMailMode(ExternalMailClient):
- """Call emacsclient in mail-mode.
-
- This only work for emacs >= 22.1.
+class EmacsMail(ExternalMailClient):
+ """Call emacsclient to have a mail buffer.
+
+ This only work for emacs >= 22.1 due to recent -e/--eval support.
+
+ The good news is that this implementation will work with all mail
+ agents registered against ``mail-user-agent``. So there is no need
+ to instantiate ExternalMailClient for each and every GNU Emacs
+ MUA.
+
+ Users just have to ensure that ``mail-user-agent`` is set according
+ to their tastes.
"""
+
_client_commands = ['emacsclient']
+ def _prepare_send_function(self):
+ """Write our wrapper function into a temporary file.
+
+ This temporary file will be loaded at runtime in
+ _get_compose_commandline function.
+
+ FIXME: this function does not remove the file. That's a wanted
+ behaviour since _get_compose_commandline won't run the send
+ mail function directly but return the eligible command line.
+ Removing our temporary file here would prevent our sendmail
+ function to work.
+
+ A possible workaround could be to load the function here with
+ emacsclient --eval '(load temp)' but this is not robust since
+ emacs could have been stopped between here and the call to
+ mail client.
+ """
+
+ _defun = r"""(defun bzr-add-mime-att (file)
+ "Attach FILe to a mail buffer as a MIME attachment."
+ (let ((agent mail-user-agent))
+ (mail-text)
+ (newline)
+ (if (and file (file-exists-p file))
+ (cond
+ ((eq agent 'sendmail-user-agent)
+ (etach-attach file))
+ ((or (eq agent 'message-user-agent)(eq agent 'gnus-user-agent))
+ (mml-attach-file file "text/x-patch" "BZR merge" "attachment"))
+ (t
+ (message "Unhandled MUA")))
+ (error "File %s does not exist." file))))
+"""
+
+ fd, temp_file = tempfile.mkstemp(prefix="emacs-bzr-send-",
+ suffix=".el")
+ try:
+ os.write(fd, _defun)
+ finally:
+ os.close(fd) # Just close the handle but do not remove the file.
+ return temp_file
+
def _get_compose_commandline(self, to, subject, attach_path):
commandline = ["--eval"]
- # Ensure we can at least have an empty mail-mode buffer
+
_to = "nil"
_subject = "nil"
@@ -323,19 +374,23 @@
_to = ("\"%s\"" % self._encode_safe(to))
if subject is not None:
_subject = ("\"%s\"" % self._encode_safe(subject))
- mmform = "(mail nil %s %s)" % (_to ,_subject)
-
- # call mail-mode, move the point to body and insert a new blank line
- # we *must* force this point movement for the case when To is not passed
- # with --mail-to. Without this, the patch could be inserted at the wrong place
- commandline.append(mmform)
- commandline.append("(mail-text)")
- commandline.append("(newline)")
-
- # ... and put a MIME attachment (if any)
+
+ # Funcall the default mail composition function
+ # This will work with any mail mode including default mail-mode
+ # User must tweak mail-user-agent variable to tell what function
+ # will be called inside compose-mail.
+ mail_cmd = "(compose-mail %s %s)" % (_to, _subject)
+ commandline.append(mail_cmd)
+
+ # Try to attach a MIME attachment using our wrapper function
if attach_path is not None:
- ifform = "(attach \"%s\")" % self._encode_path(attach_path,'attachment')
- commandline.append(ifform)
+ # Do not create a file if there is no attachment
+ lmmform = '(load "%s")' % self._prepare_send_function()
+ mmform = '(bzr-add-mime-att "%s")' % \
+ self._encode_path(attach_path, 'attachment')
+ commandline.append(lmmform)
+ commandline.append(mmform)
+
return commandline
=== modified file 'bzrlib/tests/test_mail_client.py'
--- a/bzrlib/tests/test_mail_client.py 2008-04-01 04:19:06 +0000
+++ b/bzrlib/tests/test_mail_client.py 2008-04-13 11:48:00 +0000
@@ -71,27 +71,34 @@
'Command-line item %r is unicode!' % item)
-class TestEmacsMailMode(tests.TestCase):
+class TestEmacsMail(tests.TestCase):
def test_commandline(self):
- eclient = mail_client.EmacsMailMode(None)
- commandline = eclient._get_compose_commandline(None, None, 'file%')
- self.assertEqual(['--eval', '(mail nil nil nil)',
- '(mail-text)', '(newline)',
- '(attach "file%")'], commandline)
+ eclient = mail_client.EmacsMail(None)
+
+ commandline = eclient._get_compose_commandline(None, 'Hi there!', None)
+ self.assertEqual(['--eval', '(compose-mail nil "Hi there!")'],
+ commandline)
commandline = eclient._get_compose_commandline('jrandom at example.org',
- 'Hi there!', None)
- self.assertEqual(['--eval', '(mail nil "jrandom at example.org" "Hi there!")',
- '(mail-text)', '(newline)'], commandline)
+ 'Hi there!', None)
+ self.assertEqual(['--eval',
+ '(compose-mail "jrandom at example.org" "Hi there!")'],
+ commandline)
+
+ # We won't be able to know the temporary file name at this stage
+ # so we can't raise an assertion with assertEqual
+ cmdline = eclient._get_compose_commandline(None, None, 'file%')
+ commandline = ' '.join(cmdline)
+ self.assertContainsRe(commandline, '--eval')
+ self.assertContainsRe(commandline, '(compose-mail nil nil)')
+ self.assertContainsRe(commandline, '(load .*)')
+ self.assertContainsRe(commandline, '(bzr-add-mime-att \"file%\")')
def test_commandline_is_8bit(self):
- eclient = mail_client.EmacsMailMode(None)
+ eclient = mail_client.EmacsMail(None)
commandline = eclient._get_compose_commandline(u'jrandom at example.org',
u'Hi there!', u'file%')
- self.assertEqual(['--eval', '(mail nil "jrandom at example.org" "Hi there!")',
- '(mail-text)', '(newline)',
- '(attach "file%")'], commandline)
for item in commandline:
self.assertFalse(isinstance(item, unicode),
'Command-line item %r is unicode!' % item)
More information about the bazaar-commits
mailing list