hgext/patchbomb.py
author Henrik Stuart <henrik.stuart at edlund.dk>
Wed, 08 Apr 2009 19:32:16 +0200
changeset 8025 1280934dd2dd
parent 7997 8eb9f495e150
child 8076 5ec526c1a32f
permissions -rw-r--r--
patchbomb: Support initial in-reply-to header This allows follow-up/revised patches to appear properly threaded in mail readers and in the archives, reducing noise.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
     1
'''sending Mercurial changesets as a series of patch emails
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
     2
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
     3
The series is started off with a "[PATCH 0 of N]" introduction, which
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
     4
describes the series as a whole.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
     5
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
     6
Each patch email has a Subject line of "[PATCH M of N] ...", using the
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
     7
first line of the changeset description as the subject text. The
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
     8
message contains two or three body parts:
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
     9
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    10
  The remainder of the changeset description.
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    11
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7413
diff changeset
    12
  [Optional] The result of running diffstat on the patch.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    13
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    14
  The patch itself, as generated by "hg export".
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    15
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    16
Each message refers to all of its predecessors using the In-Reply-To
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    17
and References headers, so they will show up as a sequence in threaded
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    18
mail and news readers, and in mail archives.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    19
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    20
For each changeset, you will be prompted with a diffstat summary and
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    21
the changeset summary, so you can be sure you are sending the right
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    22
changes.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    23
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    24
To enable this extension:
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    25
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    26
  [extensions]
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    27
  hgext.patchbomb =
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    28
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    29
To configure other defaults, add a section like this to your hgrc
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    30
file:
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    31
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    32
  [email]
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    33
  from = My Name <my@email>
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    34
  to = recipient1, recipient2, ...
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    35
  cc = cc1, cc2, ...
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    36
  bcc = bcc1, bcc2, ...
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    37
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    38
Then you can use the "hg email" command to mail a series of changesets
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    39
as a patchbomb.
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    40
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    41
To avoid sending patches prematurely, it is a good idea to first run
7983
7b813bdbd5d0 Change double spaces to single spaces in help texts.
Martin Geisler <mg@daimi.au.dk>
parents: 7889
diff changeset
    42
the "email" command with the "-n" option (test only). You will be
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    43
prompted for an email recipient address, a subject an an introductory
7983
7b813bdbd5d0 Change double spaces to single spaces in help texts.
Martin Geisler <mg@daimi.au.dk>
parents: 7889
diff changeset
    44
message describing the patches of your patchbomb. Then when all is
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    45
done, patchbomb messages are displayed. If PAGER environment variable
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    46
is set, your pager will be fired up once for each patchbomb message,
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    47
so you can verify everything is alright.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    48
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    49
The "-m" (mbox) option is also very useful. Instead of previewing each
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    50
patchbomb message in a pager or sending the messages directly, it will
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    51
create a UNIX mailbox file with the patch emails. This mailbox file
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    52
can be previewed with any mail user agent which supports UNIX mbox
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    53
files, e.g. with mutt:
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    54
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    55
  % mutt -R -f mbox
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    56
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    57
When you are previewing the patchbomb messages, you can use `formail'
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    58
(a utility that is commonly installed as part of the procmail
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    59
package), to send each message out:
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    60
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    61
  % formail -s sendmail -bm -t < mbox
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    62
7694
2ceeb1423544 added information to patchbomb help pointing users to hgrc(5) to configure the [smtp] section in order to send patchbombs
Bill Barry <after.fallout@gmail.com>
parents: 7685
diff changeset
    63
That should be all. Now your patchbomb is on its way out.
2ceeb1423544 added information to patchbomb help pointing users to hgrc(5) to configure the [smtp] section in order to send patchbombs
Bill Barry <after.fallout@gmail.com>
parents: 7685
diff changeset
    64
2ceeb1423544 added information to patchbomb help pointing users to hgrc(5) to configure the [smtp] section in order to send patchbombs
Bill Barry <after.fallout@gmail.com>
parents: 7685
diff changeset
    65
You can also either configure the method option in the email section
2ceeb1423544 added information to patchbomb help pointing users to hgrc(5) to configure the [smtp] section in order to send patchbombs
Bill Barry <after.fallout@gmail.com>
parents: 7685
diff changeset
    66
to be a sendmail compatable mailer or fill out the [smtp] section so
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    67
that the patchbomb extension can automatically send patchbombs
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    68
directly from the commandline. See the [email] and [smtp] sections in
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    69
hgrc(5) for details.'''
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    70
6478
a135374ed5fc patchbomb: fix cStringIO import (spotted by pychecker)
Christian Ebert <blacktrash@gmx.net>
parents: 6447
diff changeset
    71
import os, errno, socket, tempfile, cStringIO
7192
f31ba106fc19 patchbomb: mime-encode clean utf-8 patches (issue814)
Christian Ebert <blacktrash@gmx.net>
parents: 7115
diff changeset
    72
import email.MIMEMultipart, email.MIMEBase
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
    73
import email.Utils, email.Encoders, email.Generator
7685
161412a3341c patchbomb: respect diff settings
Martin Geisler <mg@daimi.au.dk>
parents: 7616
diff changeset
    74
from mercurial import cmdutil, commands, hg, mail, patch, util
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3887
diff changeset
    75
from mercurial.i18n import _
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5973
diff changeset
    76
from mercurial.node import bin
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    77
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    78
def prompt(ui, prompt, default=None, rest=': ', empty_ok=False):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    79
    if not ui.interactive:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    80
        return default
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    81
    if default:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    82
        prompt += ' [%s]' % default
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    83
    prompt += rest
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    84
    while True:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    85
        r = ui.prompt(prompt, default=default)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    86
        if r:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    87
            return r
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    88
        if default is not None:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    89
            return default
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    90
        if empty_ok:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    91
            return r
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    92
        ui.warn(_('Please enter a valid value.\n'))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    93
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    94
def cdiffstat(ui, summary, patchlines):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    95
    s = patch.diffstat(patchlines)
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7413
diff changeset
    96
    if summary:
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7413
diff changeset
    97
        ui.write(summary, '\n')
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7413
diff changeset
    98
        ui.write(s, '\n')
7600
f7739cf3833c lowercase prompts
Martin Geisler <mg@daimi.au.dk>
parents: 7547
diff changeset
    99
    ans = prompt(ui, _('does the diffstat above look okay? '), 'y')
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7413
diff changeset
   100
    if not ans.lower().startswith('y'):
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7413
diff changeset
   101
        raise util.Abort(_('diffstat rejected'))
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   102
    return s
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   103
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   104
def makepatch(ui, repo, patch, opts, _charsets, idx, total, patchname=None):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   105
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   106
    desc = []
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   107
    node = None
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   108
    body = ''
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   109
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   110
    for line in patch:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   111
        if line.startswith('#'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   112
            if line.startswith('# Node ID'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   113
                node = line.split()[-1]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   114
            continue
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   115
        if line.startswith('diff -r') or line.startswith('diff --git'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   116
            break
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   117
        desc.append(line)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   118
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   119
    if not patchname and not node:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   120
        raise ValueError
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   121
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   122
    if opts.get('attach'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   123
        body = ('\n'.join(desc[1:]).strip() or
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   124
                'Patch subject is complete summary.')
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   125
        body += '\n\n\n'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   126
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   127
    if opts.get('plain'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   128
        while patch and patch[0].startswith('# '):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   129
            patch.pop(0)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   130
        if patch:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   131
            patch.pop(0)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   132
        while patch and not patch[0].strip():
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   133
            patch.pop(0)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   134
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   135
    if opts.get('diffstat'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   136
        body += cdiffstat(ui, '\n'.join(desc), patch) + '\n\n'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   137
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   138
    if opts.get('attach') or opts.get('inline'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   139
        msg = email.MIMEMultipart.MIMEMultipart()
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   140
        if body:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   141
            msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   142
        p = mail.mimetextpatch('\n'.join(patch), 'x-patch', opts.get('test'))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   143
        binnode = bin(node)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   144
        # if node is mq patch, it will have patch file name as tag
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   145
        if not patchname:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   146
            patchtags = [t for t in repo.nodetags(binnode)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   147
                         if t.endswith('.patch') or t.endswith('.diff')]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   148
            if patchtags:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   149
                patchname = patchtags[0]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   150
            elif total > 1:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   151
                patchname = cmdutil.make_filename(repo, '%b-%n.patch',
7359
b0fa5dbd9cdd patchbomb: fix patch name generation in patch series
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7354
diff changeset
   152
                                                  binnode, seqno=idx, total=total)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   153
            else:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   154
                patchname = cmdutil.make_filename(repo, '%b.patch', binnode)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   155
        disposition = 'inline'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   156
        if opts.get('attach'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   157
            disposition = 'attachment'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   158
        p['Content-Disposition'] = disposition + '; filename=' + patchname
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   159
        msg.attach(p)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   160
    else:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   161
        body += '\n'.join(patch)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   162
        msg = mail.mimetextpatch(body, display=opts.get('test'))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   163
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   164
    subj = desc[0].strip().rstrip('. ')
7360
42f1b8cb9a60 patchbomb: add option to send intro email for a single patch (issue1120)
Chris Winter <elwintro@gmail.com>
parents: 7359
diff changeset
   165
    if total == 1 and not opts.get('intro'):
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   166
        subj = '[PATCH] ' + (opts.get('subject') or subj)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   167
    else:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   168
        tlen = len(str(total))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   169
        subj = '[PATCH %0*d of %d] %s' % (tlen, idx, total, subj)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   170
    msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   171
    msg['X-Mercurial-Node'] = node
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   172
    return msg, subj
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   173
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   174
def patchbomb(ui, repo, *revs, **opts):
4283
8625504f507c Slight refining to help text in patchbomb.py
John Goerzen <jgoerzen@complete.org>
parents: 4280
diff changeset
   175
    '''send changesets by email
1204
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
   176
4283
8625504f507c Slight refining to help text in patchbomb.py
John Goerzen <jgoerzen@complete.org>
parents: 4280
diff changeset
   177
    By default, diffs are sent in the format generated by hg export,
7983
7b813bdbd5d0 Change double spaces to single spaces in help texts.
Martin Geisler <mg@daimi.au.dk>
parents: 7889
diff changeset
   178
    one per message. The series starts with a "[PATCH 0 of N]"
4283
8625504f507c Slight refining to help text in patchbomb.py
John Goerzen <jgoerzen@complete.org>
parents: 4280
diff changeset
   179
    introduction, which describes the series as a whole.
1672
07f931af5f40 add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1670
diff changeset
   180
07f931af5f40 add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1670
diff changeset
   181
    Each patch email has a Subject line of "[PATCH M of N] ...", using
07f931af5f40 add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1670
diff changeset
   182
    the first line of the changeset description as the subject text.
7983
7b813bdbd5d0 Change double spaces to single spaces in help texts.
Martin Geisler <mg@daimi.au.dk>
parents: 7889
diff changeset
   183
    The message contains two or three body parts. First, the rest of
7b813bdbd5d0 Change double spaces to single spaces in help texts.
Martin Geisler <mg@daimi.au.dk>
parents: 7889
diff changeset
   184
    the changeset description. Next, (optionally) if the diffstat
1672
07f931af5f40 add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1670
diff changeset
   185
    program is installed, the result of running diffstat on the patch.
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   186
    Finally, the patch itself, as generated by "hg export".
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   187
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
   188
    With --outgoing, emails will be generated for patches not found in
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
   189
    the destination repository (or only those which are ancestors of
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
   190
    the specified revisions if any are provided)
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   191
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
   192
    With --bundle, changesets are selected as for --outgoing, but a
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
   193
    single email containing a binary Mercurial bundle as an attachment
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
   194
    will be sent.
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   195
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   196
    Examples:
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   197
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   198
    hg email -r 3000          # send patch 3000 only
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   199
    hg email -r 3000 -r 3001  # send patches 3000 and 3001
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   200
    hg email -r 3000:3005     # send patches 3000 through 3005
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   201
    hg email 3000             # send patch 3000 (deprecated)
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   202
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   203
    hg email -o               # send all patches not in default
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   204
    hg email -o DEST          # send all patches not in DEST
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   205
    hg email -o -r 3000       # send all ancestors of 3000 not in default
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   206
    hg email -o -r 3000 DEST  # send all ancestors of 3000 not in DEST
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   207
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   208
    hg email -b               # send bundle of all patches not in default
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   209
    hg email -b DEST          # send bundle of all patches not in DEST
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   210
    hg email -b -r 3000       # bundle of all ancestors of 3000 not in default
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   211
    hg email -b -r 3000 DEST  # bundle of all ancestors of 3000 not in DEST
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   212
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
   213
    Before using this command, you will need to enable email in your
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
   214
    hgrc. See the [email] section in hgrc(5) for details.
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   215
    '''
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   216
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   217
    _charsets = mail._charsets(ui)
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   218
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   219
    def outgoing(dest, revs):
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   220
        '''Return the revisions present locally but not in dest'''
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   221
        dest = ui.expandpath(dest or 'default-push', dest or 'default')
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   222
        revs = [repo.lookup(rev) for rev in revs]
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   223
        other = hg.repository(ui, dest)
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   224
        ui.status(_('comparing with %s\n') % dest)
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   225
        o = repo.findoutgoing(other)
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   226
        if not o:
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   227
            ui.status(_("no changes found\n"))
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   228
            return []
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   229
        o = repo.changelog.nodesbetween(o, revs or None)[0]
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   230
        return [str(repo.changelog.rev(r)) for r in o]
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   231
7615
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   232
    def getpatches(revs):
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   233
        for r in cmdutil.revrange(repo, revs):
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   234
            output = cStringIO.StringIO()
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7807
diff changeset
   235
            patch.export(repo, [r], fp=output,
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7807
diff changeset
   236
                         opts=patch.diffopts(ui, opts))
7615
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   237
            yield output.getvalue().split('\n')
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   238
4279
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   239
    def getbundle(dest):
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   240
        tmpdir = tempfile.mkdtemp(prefix='hg-email-bundle-')
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   241
        tmpfn = os.path.join(tmpdir, 'bundle')
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   242
        try:
4279
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   243
            commands.bundle(ui, repo, tmpfn, dest, **opts)
5752
84a6e463b948 patchbomb: read bundle file in binary mode
Patrick Mezard <pmezard@gmail.com>
parents: 5643
diff changeset
   244
            return open(tmpfn, 'rb').read()
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   245
        finally:
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   246
            try:
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   247
                os.unlink(tmpfn)
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   248
            except:
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   249
                pass
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   250
            os.rmdir(tmpdir)
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   251
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   252
    if not (opts.get('test') or opts.get('mbox')):
5472
23889160905a Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents: 4887
diff changeset
   253
        # really sending
4489
a11e13d50645 patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4486
diff changeset
   254
        mail.validateconfig(ui)
a11e13d50645 patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4486
diff changeset
   255
5643
eae4553b2763 patchbomb: make "hg email -b" w/o destination work as advertised
Christian Ebert <blacktrash@gmx.net>
parents: 5479
diff changeset
   256
    if not (revs or opts.get('rev')
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   257
            or opts.get('outgoing') or opts.get('bundle')
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   258
            or opts.get('patches')):
4493
ead2fa544cbf patchbomb: Fail early if no revs given to email
Bryan O'Sullivan <bos@serpentine.com>
parents: 4492
diff changeset
   259
        raise util.Abort(_('specify at least one changeset with -r or -o'))
ead2fa544cbf patchbomb: Fail early if no revs given to email
Bryan O'Sullivan <bos@serpentine.com>
parents: 4492
diff changeset
   260
4564
d48e1b5f8265 patchbomb: 0c61124ad877 moved setremoteconfig into cmdutil
Bryan O'Sullivan <bos@serpentine.com>
parents: 4493
diff changeset
   261
    cmdutil.setremoteconfig(ui, opts)
4492
c15955bde7dd patchbomb: Fix typo.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4491
diff changeset
   262
    if opts.get('outgoing') and opts.get('bundle'):
5746
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   263
        raise util.Abort(_("--outgoing mode always on with --bundle;"
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   264
                           " do not re-specify --outgoing"))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   265
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   266
    if opts.get('outgoing') or opts.get('bundle'):
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   267
        if len(revs) > 1:
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   268
            raise util.Abort(_("too many destinations"))
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   269
        dest = revs and revs[0] or None
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   270
        revs = []
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   271
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   272
    if opts.get('rev'):
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   273
        if revs:
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   274
            raise util.Abort(_('use only one form to specify the revision'))
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   275
        revs = opts.get('rev')
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   276
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   277
    if opts.get('outgoing'):
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   278
        revs = outgoing(dest, opts.get('rev'))
4279
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   279
    if opts.get('bundle'):
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   280
        opts['revs'] = revs
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   281
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   282
    # start
4566
087b3ae4f08a patchbomb: add --date option
Bryan O'Sullivan <bos@serpentine.com>
parents: 4565
diff changeset
   283
    if opts.get('date'):
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   284
        start_time = util.parsedate(opts.get('date'))
4566
087b3ae4f08a patchbomb: add --date option
Bryan O'Sullivan <bos@serpentine.com>
parents: 4565
diff changeset
   285
    else:
087b3ae4f08a patchbomb: add --date option
Bryan O'Sullivan <bos@serpentine.com>
parents: 4565
diff changeset
   286
        start_time = util.makedate()
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   287
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   288
    def genmsgid(id):
4027
2601ac9c54f0 patchbomb: fix timezone offset in message date header
Christian Ebert <blacktrash@gmx.net>
parents: 3473
diff changeset
   289
        return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn())
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   290
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   291
    def getdescription(body, sender):
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   292
        if opts.get('desc'):
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   293
            body = open(opts.get('desc')).read()
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   294
        else:
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   295
            ui.write(_('\nWrite the introductory message for the '
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   296
                       'patch series.\n\n'))
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   297
            body = ui.edit(body, sender)
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   298
        return body
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   299
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   300
    def getpatchmsgs(patches, patchnames=None):
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   301
        jumbo = []
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   302
        msgs = []
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   303
5746
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   304
        ui.write(_('This patch series consists of %d patches.\n\n')
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   305
                 % len(patches))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   306
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   307
        name = None
7616
b9bd6f789633 use enumerate instead of zip
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7615
diff changeset
   308
        for i, p in enumerate(patches):
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   309
            jumbo.extend(p)
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   310
            if patchnames:
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   311
                name = patchnames[i]
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   312
            msg = makepatch(ui, repo, p, opts, _charsets, i + 1,
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   313
                            len(patches), name)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   314
            msgs.append(msg)
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   315
7360
42f1b8cb9a60 patchbomb: add option to send intro email for a single patch (issue1120)
Chris Winter <elwintro@gmail.com>
parents: 7359
diff changeset
   316
        if len(patches) > 1 or opts.get('intro'):
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   317
            tlen = len(str(len(patches)))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   318
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   319
            subj = '[PATCH %0*d of %d] %s' % (
5786
c69ef6fdb092 patchbomb: simplify some line continuations
Christian Ebert <blacktrash@gmx.net>
parents: 5785
diff changeset
   320
                tlen, 0, len(patches),
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   321
                opts.get('subject') or
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   322
                prompt(ui, 'Subject:',
5786
c69ef6fdb092 patchbomb: simplify some line continuations
Christian Ebert <blacktrash@gmx.net>
parents: 5785
diff changeset
   323
                       rest=' [PATCH %0*d of %d] ' % (tlen, 0, len(patches))))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   324
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   325
            body = ''
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   326
            if opts.get('diffstat'):
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   327
                d = cdiffstat(ui, _('Final summary:\n'), jumbo)
5785
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   328
                if d:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   329
                    body = '\n' + d
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   330
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   331
            body = getdescription(body, sender)
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   332
            msg = mail.mimeencode(ui, body, _charsets, opts.get('test'))
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   333
            msg['Subject'] = mail.headencode(ui, subj, _charsets,
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   334
                                             opts.get('test'))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   335
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   336
            msgs.insert(0, (msg, subj))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   337
        return msgs
2704
99e7cf6bd2f7 make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents: 2443
diff changeset
   338
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   339
    def getbundlemsgs(bundle):
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   340
        subj = (opts.get('subject')
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   341
                or prompt(ui, 'Subject:', 'A bundle for your repository'))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   342
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   343
        body = getdescription('', sender)
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   344
        msg = email.MIMEMultipart.MIMEMultipart()
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   345
        if body:
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   346
            msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   347
        datapart = email.MIMEBase.MIMEBase('application', 'x-mercurial-bundle')
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   348
        datapart.set_payload(bundle)
7889
5ac1a72e5b74 patchbomb: option to set the name of bundle attachment (issue1452)
John Mulligan <phlogistonjohn@asynchrono.us>
parents: 7874
diff changeset
   349
        bundlename = '%s.hg' % opts.get('bundlename', 'bundle')
4284
a04141f51056 Add a filename for the bundle
John Goerzen <jgoerzen@complete.org>
parents: 4283
diff changeset
   350
        datapart.add_header('Content-Disposition', 'attachment',
7889
5ac1a72e5b74 patchbomb: option to set the name of bundle attachment (issue1452)
John Mulligan <phlogistonjohn@asynchrono.us>
parents: 7874
diff changeset
   351
                            filename=bundlename)
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   352
        email.Encoders.encode_base64(datapart)
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   353
        msg.attach(datapart)
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   354
        msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   355
        return [(msg, subj)]
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   356
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   357
    sender = (opts.get('from') or ui.config('email', 'from') or
2198
564034552f7f rename [patchbomb] section to [email] section in hgrc. old name still ok.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2165
diff changeset
   358
              ui.config('patchbomb', 'from') or
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   359
              prompt(ui, 'From', ui.username()))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   360
7615
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   361
    # internal option used by pbranches
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   362
    patches = opts.get('patches')
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   363
    if patches:
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   364
        msgs = getpatchmsgs(patches, opts.get('patchnames'))
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   365
    elif opts.get('bundle'):
4279
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   366
        msgs = getbundlemsgs(getbundle(dest))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   367
    else:
7615
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   368
        msgs = getpatchmsgs(list(getpatches(revs)))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   369
1154
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
   370
    def getaddrs(opt, prpt, default = None):
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   371
        addrs = opts.get(opt) or (ui.config('email', opt) or
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   372
                                  ui.config('patchbomb', opt) or
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   373
                                  prompt(ui, prpt, default)).split(',')
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   374
        return [mail.addressencode(ui, a.strip(), _charsets, opts.get('test'))
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   375
                for a in addrs if a.strip()]
4485
82bc6aef8b43 patchbomb: Don't prompt for headers until sure we have revs to export.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4284
diff changeset
   376
1154
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
   377
    to = getaddrs('to', 'To')
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
   378
    cc = getaddrs('cc', 'Cc', '')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   379
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   380
    bcc = opts.get('bcc') or (ui.config('email', 'bcc') or
2679
f1de91be1d87 optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents: 2443
diff changeset
   381
                          ui.config('patchbomb', 'bcc') or '').split(',')
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   382
    bcc = [mail.addressencode(ui, a.strip(), _charsets, opts.get('test'))
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   383
           for a in bcc if a.strip()]
2679
f1de91be1d87 optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents: 2443
diff changeset
   384
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   385
    ui.write('\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   386
8025
1280934dd2dd patchbomb: Support initial in-reply-to header
Henrik Stuart <henrik.stuart at edlund.dk>
parents: 7997
diff changeset
   387
    parent = opts.get('in_reply_to') or None
2443
bd9c39e8f38b patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 2292
diff changeset
   388
1827
26dd4ae77b7b get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 1702
diff changeset
   389
    sender_addr = email.Utils.parseaddr(sender)[1]
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   390
    sender = mail.addressencode(ui, sender, _charsets, opts.get('test'))
5973
ea77f6f77514 patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents: 5948
diff changeset
   391
    sendmail = None
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   392
    for m, subj in msgs:
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   393
        try:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   394
            m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   395
        except TypeError:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   396
            m['Message-Id'] = genmsgid('patchbomb')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   397
        if parent:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   398
            m['In-Reply-To'] = parent
7413
0b6428da1f22 email: add References field in the header
Benoit Allard <benoit@aeteurope.nl>
parents: 7360
diff changeset
   399
            m['References'] = parent
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   400
        else:
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   401
            parent = m['Message-Id']
6229
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
   402
        m['Date'] = util.datestr(start_time, "%a, %d %b %Y %H:%M:%S %1%2")
2443
bd9c39e8f38b patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 2292
diff changeset
   403
4027
2601ac9c54f0 patchbomb: fix timezone offset in message date header
Christian Ebert <blacktrash@gmx.net>
parents: 3473
diff changeset
   404
        start_time = (start_time[0] + 1, start_time[1])
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   405
        m['From'] = sender
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   406
        m['To'] = ', '.join(to)
5785
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   407
        if cc:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   408
            m['Cc']  = ', '.join(cc)
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   409
        if bcc:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   410
            m['Bcc'] = ', '.join(bcc)
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   411
        if opts.get('test'):
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   412
            ui.status(_('Displaying '), subj, ' ...\n')
4596
8e37342cb05d patchbomb: flush ui before delegating to pager.
Patrick Mezard <pmezard@gmail.com>
parents: 4142
diff changeset
   413
            ui.flush()
4599
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
   414
            if 'PAGER' in os.environ:
6548
962eb403165b replace usage of os.popen() with util.popen()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6478
diff changeset
   415
                fp = util.popen(os.environ['PAGER'], 'w')
4599
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
   416
            else:
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
   417
                fp = ui
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   418
            generator = email.Generator.Generator(fp, mangle_from_=False)
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   419
            try:
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   420
                generator.flatten(m, 0)
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   421
                fp.write('\n')
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   422
            except IOError, inst:
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   423
                if inst.errno != errno.EPIPE:
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   424
                    raise
4599
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
   425
            if fp is not ui:
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
   426
                fp.close()
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   427
        elif opts.get('mbox'):
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   428
            ui.status(_('Writing '), subj, ' ...\n')
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5866
diff changeset
   429
            fp = open(opts.get('mbox'), 'In-Reply-To' in m and 'ab+' or 'wb+')
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   430
            generator = email.Generator.Generator(fp, mangle_from_=True)
6229
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
   431
            date = util.datestr(start_time, '%a %b %d %H:%M:%S %Y')
1702
e291d9a30bef add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents: 1691
diff changeset
   432
            fp.write('From %s %s\n' % (sender_addr, date))
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   433
            generator.flatten(m, 0)
1702
e291d9a30bef add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents: 1691
diff changeset
   434
            fp.write('\n\n')
e291d9a30bef add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents: 1691
diff changeset
   435
            fp.close()
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   436
        else:
5973
ea77f6f77514 patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents: 5948
diff changeset
   437
            if not sendmail:
ea77f6f77514 patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents: 5948
diff changeset
   438
                sendmail = mail.connect(ui)
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   439
            ui.status(_('Sending '), subj, ' ...\n')
2790
58a679745b38 mailbomb: add a comment and remove the bcc in a more pythonic way
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2732
diff changeset
   440
            # Exim does not remove the Bcc field
58a679745b38 mailbomb: add a comment and remove the bcc in a more pythonic way
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2732
diff changeset
   441
            del m['Bcc']
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   442
            fp = cStringIO.StringIO()
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   443
            generator = email.Generator.Generator(fp, mangle_from_=False)
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   444
            generator.flatten(m, 0)
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   445
            sendmail(sender, to + bcc + cc, fp.getvalue())
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   446
7352
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   447
emailopts = [
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   448
          ('a', 'attach', None, _('send patches as attachments')),
5819
89ea99c7bdfd patchbomb: attachment options changed
Dennis Schoen <ds@1d10t.de>
parents: 5818
diff changeset
   449
          ('i', 'inline', None, _('send patches as inline attachments')),
7807
bd8f44638847 help: miscellaneous language fixes
timeless <timeless@gmail.com>
parents: 7694
diff changeset
   450
          ('', 'bcc', [], _('email addresses of blind carbon copy recipients')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   451
          ('c', 'cc', [], _('email addresses of copy recipients')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   452
          ('d', 'diffstat', None, _('add diffstat output to messages')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   453
          ('', 'date', '', _('use the given date as the sending date')),
4887
2f09df302f30 patchbomb: add --desc, to specify a file containing a series description
Bryan O'Sullivan <bos@serpentine.com>
parents: 4730
diff changeset
   454
          ('', 'desc', '', _('use the given file as the series description')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   455
          ('f', 'from', '', _('email address of sender')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   456
          ('n', 'test', None, _('print messages that would be sent')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   457
          ('m', 'mbox', '',
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   458
           _('write messages to mbox file instead of sending them')),
7352
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   459
          ('s', 'subject', '',
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   460
           _('subject of first message (intro or single patch)')),
8025
1280934dd2dd patchbomb: Support initial in-reply-to header
Henrik Stuart <henrik.stuart at edlund.dk>
parents: 7997
diff changeset
   461
          ('', 'in-reply-to', '',
1280934dd2dd patchbomb: Support initial in-reply-to header
Henrik Stuart <henrik.stuart at edlund.dk>
parents: 7997
diff changeset
   462
           _('"message identifier to reply to"')),
7352
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   463
          ('t', 'to', [], _('email addresses of recipients')),
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   464
         ]
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   465
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   466
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   467
cmdtable = {
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   468
    "email":
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   469
        (patchbomb,
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   470
         [('g', 'git', None, _('use git extended diff format')),
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   471
          ('', 'plain', None, _('omit hg patch header')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   472
          ('o', 'outgoing', None,
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   473
           _('send changes not found in the target repository')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   474
          ('b', 'bundle', None,
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   475
           _('send changes not in target as a binary bundle')),
7889
5ac1a72e5b74 patchbomb: option to set the name of bundle attachment (issue1452)
John Mulligan <phlogistonjohn@asynchrono.us>
parents: 7874
diff changeset
   476
          ('', 'bundlename', 'bundle',
5ac1a72e5b74 patchbomb: option to set the name of bundle attachment (issue1452)
John Mulligan <phlogistonjohn@asynchrono.us>
parents: 7874
diff changeset
   477
           _('file name of the bundle attachment')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   478
          ('r', 'rev', [], _('a revision to send')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   479
          ('', 'force', None,
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   480
           _('run even when remote repository is unrelated (with -b)')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   481
          ('', 'base', [],
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   482
           _('a base changeset to specify instead of a destination (with -b)')),
7360
42f1b8cb9a60 patchbomb: add option to send intro email for a single patch (issue1120)
Chris Winter <elwintro@gmail.com>
parents: 7359
diff changeset
   483
          ('', 'intro', None,
42f1b8cb9a60 patchbomb: add option to send intro email for a single patch (issue1120)
Chris Winter <elwintro@gmail.com>
parents: 7359
diff changeset
   484
           _('send an introduction email for a single patch')),
7352
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   485
         ] + emailopts + commands.remoteopts,
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   486
         _('hg email [OPTION]... [DEST]...'))
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   487
}